Размещение с помощью якорей
В дополнение к более традиционным Grid, Row и Column, Qt Quick также предоставляет способ компоновки элементов с использованием концепции якорей. Каждый элемент можно представить как имеющий набор из 7 невидимых "линий якорей": left, horizontalCenter, right, top, verticalCenter, baseline и bottom.
Линия базовой отметки (не показана выше) соответствует воображаемой линии, на которой располагается текст. Для элементов без текста она совпадает с линией 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; ... } Указав несколько горизонтальных или вертикальных якорей, можно контролировать размер элемента. Ниже, rect2 привязан к правому краю rect1 и левому краю 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 к левому, правому, верхнему и нижнему краям целевого элемента. anchors.centerIn — ещё один удобный якорь, эквивалентный установке якорей verticalCenter и horizontalCenter к verticalCenter и horizontalCenter целевого элемента.
Отступы и смещения якорей
Система якорей также позволяет задавать отступы и смещения для якорей элемента. Отступы определяют количество пустого пространства, которое должно оставаться снаружи от якоря элемента, а смещения позволяют манипулировать позицией с помощью центральных линий якорей. Элемент может задавать свои отступы якорей индивидуально через leftMargin, rightMargin, topMargin и bottomMargin, или использовать anchors.margins для задания одинакового значения отступа для всех четырёх сторон. Смещения якорей задаются с помощью horizontalCenterOffset, verticalCenterOffset и baselineOffset.
Следующий пример задаёт левый отступ:
Rectangle { id: rect1; ... }
Rectangle { id: rect2; anchors.left: rect1.right; anchors.leftMargin: 5; ... } В этом случае отступ в 5 пикселей резервируется слева от rect2, что приводит к следующему:
Примечание: Отступы якорей применяются только к якорям; они не являются общим способом применения отступов к элементу 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, результат неопределён, так как неясно, должен ли элемент использовать привязку или абсолютное позиционирование. То же самое можно сказать о задании положения y и высоты height с anchors.top и anchors.bottom, или установке anchors.fill наряду с width или height. То же самое относится к использованию позиционеров, таких как Row и Grid, которые могут устанавливать свойства x и y элемента. Если вы хотите перейти от использования привязки к абсолютной позиции, можно очистить значение якоря, установив его в undefined.
© The Qt Company Ltd
Licensed under the GNU Free Documentation License, Version 1.3.
https://doc.qt.io/qt-6.1/qtquick-positioning-anchors.html