アンカーを使ったポジショニング

より伝統的なGridRowColumnQt Quick に加えて、アンカーという概念を使ってアイテムをレイアウトする方法もあります。各アイテムは、7本の目に見えない「アンカー・ライン」を持っていると考えることができる:left horizontalCenterrighttopverticalCenterbaselinebottom

ベースライン(上の写真には写っていない)は、テキストが置かれる想像上の線に相当する。テキストがないアイテムの場合はtopと同じです。

Qt Quick アンカーシステムでは、異なるアイテムのアンカーライン間の関係を定義することができます。例えば、次のように書くことができます:

Rectangle { id: rect1; ... }
Rectangle { id: rect2; anchors.left: rect1.right; ... }

こ の場合、rect2の左端はrect1 の右端に結合 さ れ、 下 記の よ う にな り ます:

複数のアンカーを指定することもできます。たとえば

Rectangle { id: rect1; ... }
Rectangle { id: rect2; anchors.left: rect1.right; anchors.top: rect1.bottom; ... }

複数の水平または垂直アンカーを指定することで、アイテムのサイズを制御することができます。下図では、rect2rect1の右とrect3 の左にアンカーされている。青い矩形のどちらかを動かすと、rect2は必要に応じて伸び縮みする:

Rectangle { id: rect1; x: 0; ... }
Rectangle { id: rect2; anchors.left: rect1.right; anchors.right: rect3.left; ... }
Rectangle { id: rect3; x: 150; ... }

anchors.fillは便利なアンカーで、left,right,top,bottomアンカーをターゲットアイテムのleft,right,top,bottomに設定するのと同じです。anchors.centerInも便利なアンカーで、verticalCenterアンカーとhorizontalCenterアンカーをターゲットアイテムのverticalCenterアンカーとhorizontalCenterアンカーに設定するのと同じです。

アンカーのマージンとオフセット

アンカーシステムでは、アイテムのアンカーにマージンと オフセットを指定することもできます。マージンは、アイテムのアンカーの外側に残す余白の量を指定し、オフセットは、中央のアンカーラインを使用して位置を操作できるようにします。アイテムのアンカーマージンは、leftMarginrightMargintopMarginbottomMargin を使って個別に指定することも、anchors.margins を使って4辺すべてに同じマージン値を指定することもできます。アンカーオフセットはhorizontalCenterOffsetverticalCenterOffsetbaselineOffset を使って指定します。

次の例では左マージンを指定しています:

Rectangle { id: rect1; ... }
Rectangle { id: rect2; anchors.left: rect1.right; anchors.leftMargin: 5; ... }

こ の場合、rect2 の左に 5 ピ クセルの余白が確保 さ れ、 下 記の よ う にな り ます:

注: アンカーマージンはアンカーにのみ適用され、Item にマージンを適用する一般的な手段ではありません。アンカーマージンが辺に指定されていても、その項目がその辺上のどの項目にもアンカーされていない場合、マージンは適用されません。

アンカーの変更

Qt Quick は、状態のアンカーを指定するための タイプを提供します。AnchorChanges

State {
    name: "anchorRight"
    AnchorChanges {
        target: rect2
        anchors.right: parent.right
        anchors.left: undefined  //remove the left anchor
    }
}

AnchorChanges は、 タイプを使ってアニメーションさせることができます。AnchorAnimation

Transition {
    AnchorAnimation {}  //animates any AnchorChanges in the corresponding state change
}

アンカーは、JavaScript内で命令的に変更することもできます。しかし、これらの変更は注意深く順序付ける必要があります。次の例はその問題を示している:

//bad code
Rectangle {
    width: 50
    anchors.left: parent.left

    function reanchorToRight() {
        anchors.right = parent.right
        anchors.left = undefined
    }
}

reanchorToRight 、この関数はまず右アンカーを設定する。その時点で、左右両方のアンカーが設定され、アイテムは親を埋めるように水平に引き伸ばされる。左アンカーの設定が解除されると、新しい幅が維持されます。したがって、JavaScriptでアンカーを更新する場合は、まず不要になったアンカーを解除し、次に必要な新しいアンカーを設定します:

Rectangle {
    width: 50
    anchors.left: parent.left

    function reanchorToRight() {
        anchors.left = undefined
        anchors.right = parent.right
    }
}

バインディングの評価順序は定義されていないため、条件付きバインディングでアンカーを変更することはお勧めしません。次の例では、バインディングの更新時に左右両方のアンカーが同時に設定されるため、矩形は最終的に親の幅いっぱいにまで大きくなります。

//bad code
Rectangle {
    width: 50; height: 50
    anchors.left: state == "right" ? undefined : parent.left;
    anchors.right: state == "right" ? parent.right : undefined;
}

これはAnchorChanges を使うように書き換えるべきです。AnchorChanges は自動的に内部で順序の問題を処理するからです。

制限事項

パフォーマンス上の理由から、項目をアンカーできるのはその兄弟と直接の親だけです。例えば、以下のようなアンカーは無効であり、警告が発生します:

//bad code
Item {
    id: group1
    Rectangle { id: rect1; ... }
}
Item {
    id: group2
    Rectangle { id: rect2; anchors.left: rect1.right; ... }    // invalid anchor!
}

また、アンカーベースのレイアウトは絶対配置と混在できません。アイテムがx の位置を指定し、さらにanchors.left を設定したり、左右の端をアンカーで固定し、さらにwidth を設定したりすると、そのアイテムがアンカーを使うべきか絶対配置を使うべきかがはっきりしないため、結果は未定義になります。アイテムのyheightanchors.topanchors.bottom と一緒に設定したり、anchors.fillwidthheight と一緒に設定する場合も同様です。 Row や Grid などのポジショナを使用する場合も同様で、アイテムのxy プロパティを設定することができます。アンカー・ベースのポジショニングから絶対ポジショニングに変更したい場合は、undefined に設定することでアンカー値をクリアできます。

© 2025 The Qt Company Ltd. Documentation contributions included herein are the copyrights of their respective owners. The documentation provided herein is licensed under the terms of the GNU Free Documentation License version 1.3 as published by the Free Software Foundation. Qt and respective logos are trademarks of The Qt Company Ltd. in Finland and/or other countries worldwide. All other trademarks are property of their respective owners.