QML / Qt Quick 奇怪的布局
QML / Qt Quick weird layout
我正在使用 QML (Qt Quick) 来设置应用程序的 GUI,但我遇到了奇怪的行为。
这是我最初的一段代码:
import QtQuick 2.7
import QtQuick.Controls 2.0
import QtQuick.Layouts 1.3
Rectangle {
id: rectangle1
color: palette.grey
ColumnLayout
{
id: columnLayout1
Label
{
id: label1
text: qsTr("Target")
font.pointSize: 22
}
ProgressBar
{
id: progressBar1
value: 0.5
}
} }
... 给出布局:
然后我锚定中心:
import QtQuick 2.7
import QtQuick.Controls 2.0
import QtQuick.Layouts 1.3
Rectangle
{
id: rectangle1
color: palette.grey
ColumnLayout
{
id: columnLayout1
anchors.horizontalCenter: parent.horizontalCenter
anchors.verticalCenter: parent.verticalCenter
Label
{
id: label1
text: qsTr("Target")
font.pointSize: 22
}
ProgressBar
{
id: progressBar1
value: 0.5
}
}
}
没问题,我得到:
现在当我旋转滑块时出现问题:
import QtQuick 2.7
import QtQuick.Controls 2.0
import QtQuick.Layouts 1.3
Rectangle
{
id: rectangle1
color: palette.grey
ColumnLayout
{
id: columnLayout1
anchors.horizontalCenter: parent.horizontalCenter
anchors.verticalCenter: parent.verticalCenter
Label
{
id: label1
text: qsTr("Target")
font.pointSize: 22
}
ProgressBar
{
id: progressBar1
rotation: 90
value: 0.5
}
}
}
在这里我期待 Qt 旋转滑块并使用旋转的滑块来计算布局,但事实并非如此。实际上布局似乎是在滑块未旋转的情况下计算的,然后只有滑块旋转。这最终得到一个不再是列的布局:
这看起来有点问题,不是吗?还是我做错了什么?
现在当我将滑块包裹在一个项目中时出现另一个问题(我实际上是在玩项目以查看是否可以找到解决方法):
import QtQuick 2.7
import QtQuick.Controls 2.0
import QtQuick.Layouts 1.3
Rectangle
{
id: rectangle1
color: palette.grey
ColumnLayout
{
id: columnLayout1
anchors.horizontalCenter: parent.horizontalCenter
anchors.verticalCenter: parent.verticalCenter
Label
{
id: label1
text: qsTr("Target")
font.pointSize: 22
}
Item
{
ProgressBar
{
id: progressBar1
value: 0.5
}
}
}
}
在这种情况下,我得到的是标签上方的滑块(尽管它在代码中定义在它之后):
这对我来说也很奇怪...有人知道我做错了什么吗?
请注意,屏幕截图是从 Designer 捕获的,但 运行 该程序会导致完全相同的问题。
亲切的问候,
安托万·伦纽特。
Now things go wrong when I rotate the slider
旋转不影响 width
或 height
属性。您可以通过将以下行添加到 ProgressBar
:
来检查这一点
onWidthChanged: print("width", width)
onHeightChanged: print("height", height)
如果 ProgressBar
有一个 orientation
属性,就像在 Qt Quick Controls 1 中一样,您可以使用它来代替 rotation
。旋转栏时也不能简单地翻转 width
和 height
,因为布局使用 implicitWidth
和 implicitHeight
,而不是 width
和 height
:
import QtQuick 2.7
import QtQuick.Controls 2.0
import QtQuick.Layouts 1.3
import QtQuick.Controls 2.1
ApplicationWindow {
width: 400
height: 300
visible: true
ColumnLayout {
id: columnLayout1
anchors.horizontalCenter: parent.horizontalCenter
anchors.verticalCenter: parent.verticalCenter
Label {
id: label1
text: qsTr("Target")
font.pointSize: 22
}
ProgressBar {
id: progressBar1
rotation: 90
width: implicitHeight
height: implicitWidth
value: 0.5
}
}
}
您可以自己计算 implicitWidth
和 implicitHeight
,但这并不好。
Now another problem occurs when I wrap the slider in an Item
你走在正确的轨道上。正如 this 回答中提到的,您需要给 Item
一个尺寸。您可以这样做:
import QtQuick 2.7
import QtQuick.Controls 2.0
import QtQuick.Layouts 1.3
import QtQuick.Controls 2.1
ApplicationWindow {
width: 400
height: 300
visible: true
ColumnLayout {
id: columnLayout1
anchors.horizontalCenter: parent.horizontalCenter
anchors.verticalCenter: parent.verticalCenter
Label {
id: label1
text: qsTr("Target")
font.pointSize: 22
}
Item {
implicitWidth: progressBar1.implicitHeight
implicitHeight: progressBar1.implicitWidth
ProgressBar {
id: progressBar1
rotation: 90
value: 0.5
}
}
}
}
请注意,进度条的位置仍然不正确。那是因为default transform origin for items is in the centre。将其设置为 BottomLeft
有效:
import QtQuick 2.7
import QtQuick.Controls 2.0
import QtQuick.Layouts 1.3
import QtQuick.Controls 2.1
ApplicationWindow {
width: 400
height: 300
visible: true
ColumnLayout {
id: columnLayout1
anchors.horizontalCenter: parent.horizontalCenter
anchors.verticalCenter: parent.verticalCenter
Label {
id: label1
text: qsTr("Target")
font.pointSize: 22
}
Item {
implicitWidth: progressBar1.implicitHeight
implicitHeight: progressBar1.implicitWidth + progressBar1.implicitHeight
ProgressBar {
id: progressBar1
rotation: 90
transformOrigin: Item.BottomLeft
value: 0.5
}
}
}
}
请注意,您还必须将条形的 implicitHeight
添加到 Item
的 implicitHeight
,以说明我们所做的变换原点更改。
我强烈建议您在 bugreports.qt.io 上创建方向 属性 的建议。 :)
我正在使用 QML (Qt Quick) 来设置应用程序的 GUI,但我遇到了奇怪的行为。
这是我最初的一段代码:
import QtQuick 2.7
import QtQuick.Controls 2.0
import QtQuick.Layouts 1.3
Rectangle {
id: rectangle1
color: palette.grey
ColumnLayout
{
id: columnLayout1
Label
{
id: label1
text: qsTr("Target")
font.pointSize: 22
}
ProgressBar
{
id: progressBar1
value: 0.5
}
} }
... 给出布局:
然后我锚定中心:
import QtQuick 2.7
import QtQuick.Controls 2.0
import QtQuick.Layouts 1.3
Rectangle
{
id: rectangle1
color: palette.grey
ColumnLayout
{
id: columnLayout1
anchors.horizontalCenter: parent.horizontalCenter
anchors.verticalCenter: parent.verticalCenter
Label
{
id: label1
text: qsTr("Target")
font.pointSize: 22
}
ProgressBar
{
id: progressBar1
value: 0.5
}
}
}
没问题,我得到:
现在当我旋转滑块时出现问题:
import QtQuick 2.7
import QtQuick.Controls 2.0
import QtQuick.Layouts 1.3
Rectangle
{
id: rectangle1
color: palette.grey
ColumnLayout
{
id: columnLayout1
anchors.horizontalCenter: parent.horizontalCenter
anchors.verticalCenter: parent.verticalCenter
Label
{
id: label1
text: qsTr("Target")
font.pointSize: 22
}
ProgressBar
{
id: progressBar1
rotation: 90
value: 0.5
}
}
}
在这里我期待 Qt 旋转滑块并使用旋转的滑块来计算布局,但事实并非如此。实际上布局似乎是在滑块未旋转的情况下计算的,然后只有滑块旋转。这最终得到一个不再是列的布局:
这看起来有点问题,不是吗?还是我做错了什么?
现在当我将滑块包裹在一个项目中时出现另一个问题(我实际上是在玩项目以查看是否可以找到解决方法):
import QtQuick 2.7
import QtQuick.Controls 2.0
import QtQuick.Layouts 1.3
Rectangle
{
id: rectangle1
color: palette.grey
ColumnLayout
{
id: columnLayout1
anchors.horizontalCenter: parent.horizontalCenter
anchors.verticalCenter: parent.verticalCenter
Label
{
id: label1
text: qsTr("Target")
font.pointSize: 22
}
Item
{
ProgressBar
{
id: progressBar1
value: 0.5
}
}
}
}
在这种情况下,我得到的是标签上方的滑块(尽管它在代码中定义在它之后):
这对我来说也很奇怪...有人知道我做错了什么吗?
请注意,屏幕截图是从 Designer 捕获的,但 运行 该程序会导致完全相同的问题。
亲切的问候,
安托万·伦纽特。
Now things go wrong when I rotate the slider
旋转不影响 width
或 height
属性。您可以通过将以下行添加到 ProgressBar
:
onWidthChanged: print("width", width)
onHeightChanged: print("height", height)
如果 ProgressBar
有一个 orientation
属性,就像在 Qt Quick Controls 1 中一样,您可以使用它来代替 rotation
。旋转栏时也不能简单地翻转 width
和 height
,因为布局使用 implicitWidth
和 implicitHeight
,而不是 width
和 height
:
import QtQuick 2.7
import QtQuick.Controls 2.0
import QtQuick.Layouts 1.3
import QtQuick.Controls 2.1
ApplicationWindow {
width: 400
height: 300
visible: true
ColumnLayout {
id: columnLayout1
anchors.horizontalCenter: parent.horizontalCenter
anchors.verticalCenter: parent.verticalCenter
Label {
id: label1
text: qsTr("Target")
font.pointSize: 22
}
ProgressBar {
id: progressBar1
rotation: 90
width: implicitHeight
height: implicitWidth
value: 0.5
}
}
}
您可以自己计算 implicitWidth
和 implicitHeight
,但这并不好。
Now another problem occurs when I wrap the slider in an Item
你走在正确的轨道上。正如 this 回答中提到的,您需要给 Item
一个尺寸。您可以这样做:
import QtQuick 2.7
import QtQuick.Controls 2.0
import QtQuick.Layouts 1.3
import QtQuick.Controls 2.1
ApplicationWindow {
width: 400
height: 300
visible: true
ColumnLayout {
id: columnLayout1
anchors.horizontalCenter: parent.horizontalCenter
anchors.verticalCenter: parent.verticalCenter
Label {
id: label1
text: qsTr("Target")
font.pointSize: 22
}
Item {
implicitWidth: progressBar1.implicitHeight
implicitHeight: progressBar1.implicitWidth
ProgressBar {
id: progressBar1
rotation: 90
value: 0.5
}
}
}
}
请注意,进度条的位置仍然不正确。那是因为default transform origin for items is in the centre。将其设置为 BottomLeft
有效:
import QtQuick 2.7
import QtQuick.Controls 2.0
import QtQuick.Layouts 1.3
import QtQuick.Controls 2.1
ApplicationWindow {
width: 400
height: 300
visible: true
ColumnLayout {
id: columnLayout1
anchors.horizontalCenter: parent.horizontalCenter
anchors.verticalCenter: parent.verticalCenter
Label {
id: label1
text: qsTr("Target")
font.pointSize: 22
}
Item {
implicitWidth: progressBar1.implicitHeight
implicitHeight: progressBar1.implicitWidth + progressBar1.implicitHeight
ProgressBar {
id: progressBar1
rotation: 90
transformOrigin: Item.BottomLeft
value: 0.5
}
}
}
}
请注意,您还必须将条形的 implicitHeight
添加到 Item
的 implicitHeight
,以说明我们所做的变换原点更改。
我强烈建议您在 bugreports.qt.io 上创建方向 属性 的建议。 :)