Qt 为什么定位到ApplicationWindow的项目的大小为零?
我需要一些像素完美的元素,还有一些应该可以调整大小,所以我尽量避免布局,只使用锚 如果我有一个固定大小的项目作为“主画布”,我可以通过锚定来实现我的目标。但是,它不适用于主窗口。如果我有一个锚定到主窗口的项目,则其大小报告为零Qt 为什么定位到ApplicationWindow的项目的大小为零?,qt,user-interface,qml,Qt,User Interface,Qml,我需要一些像素完美的元素,还有一些应该可以调整大小,所以我尽量避免布局,只使用锚 如果我有一个固定大小的项目作为“主画布”,我可以通过锚定来实现我的目标。但是,它不适用于主窗口。如果我有一个锚定到主窗口的项目,则其大小报告为零 ApplicationWindow { id:主窗口 宽度:1024 身高:768 最小宽度:800 最低高度:480 Component.onCompleted:{console.log(“主窗口宽度:”+width)} 项目 { id:topLevelItem 锚定。
ApplicationWindow
{
id:主窗口
宽度:1024
身高:768
最小宽度:800
最低高度:480
Component.onCompleted:{console.log(“主窗口宽度:”+width)}
项目
{
id:topLevelItem
锚定。填充:父级
Component.onCompleted:{console.log(“topLevelItem width:+width)}
}
}
有趣的是,topLevelItem
的宽度被打印为0
,而mainWindow
的宽度被正确打印为1024
我添加了一些元素,现在变得很奇怪:
ApplicationWindow
{
id:主窗口
宽度:1024
身高:768
最小宽度:800
最低高度:480
Component.onCompleted:{console.log(“主窗口宽度:”+width)}
项目
{
id:topLevelItem
锚定。填充:父级
Component.onCompleted:{console.log(“topLevelItem width:+width)}
矩形
{
身份证号码:红色
anchors.top:parent.top
.bottom:parent.bottom
anchors.left:parent.left
宽度:100
颜色:“FF0000”
Component.onCompleted:{console.log(“红色宽度:“+width”)}
}
矩形
{
id:绿色
anchors.top:parent.top
.bottom:parent.bottom
左:红色。右
右:蓝色。左
颜色:“00FF00”
Component.onCompleted:{console.log(“绿色宽度:“+width”)}
}
矩形
{
id:蓝色
anchors.top:parent.top
.bottom:parent.bottom
anchors.right:父项.right
宽度:50
颜色:“0000FF”
Component.onCompleted:{console.log(“蓝色宽度:“+width”)}
}
}
}
一切都按原样显示。左侧有一个100像素的垂直红色条,右侧有一个50像素的垂直蓝色条,其余部分用绿色填充
令人惊讶的是,尺寸是错误的:
qml: topLevelItem width: 0
qml: blue width: 50
qml: green width: -150
qml: red width: 100
qml: mainWindow width: 1024
除主窗口
外,所有对象的高度均报告为零
我需要访问大小,特别是中间区域的大小,因为它必须影响其他元素的放置类型,这取决于可用空间
这种奇怪行为的原因是什么?我做错什么了吗?如何才能正确访问中间矩形的大小?QML是一种声明性语言,这意味着如果您试图过多地依赖于某些事物的求值顺序,您可能会发现自己在与它作斗争。如果在更改时打印出
topLevelItem
的width
,您将看到它最终是正确的:
import QtQuick 2.7
import QtQuick.Controls 1.0
ApplicationWindow {
id: mainWindow
width: 1024
height: 768
minimumWidth: 800
minimumHeight: 480
visible: true
Component.onCompleted: console.log("mainWindow width: " + width)
Item {
id: topLevelItem
anchors.fill: parent
onWidthChanged: print("topLevelItem width: " + width)
Component.onCompleted: console.log("topLevelItem width: " + width)
}
}
输出:
qml: topLevelItem width: 0
qml: mainWindow width: 1024
qml: topLevelItem width: 1024
我不确定到底发生了什么,但很可能窗口首先得到它的大小,然后告诉contentItem
,它可以开始布置它的项目并给出它们的大小。这是异步发生的,这也是为什么在某些情况下不应该依赖命令式代码的原因之一
还值得指出的是,在使用布局时,您可以同时拥有像素完美的项目和可调整大小的项目;例如,使用
Layout.minimumWidth
和Layout.maximumWidth
强制使用某些大小。QML是一种声明性语言,这意味着如果您试图过多地依赖某些事物的评估顺序,您可能会发现自己在与之抗争。如果在更改时打印出topLevelItem
的width
,您将看到它最终是正确的:
import QtQuick 2.7
import QtQuick.Controls 1.0
ApplicationWindow {
id: mainWindow
width: 1024
height: 768
minimumWidth: 800
minimumHeight: 480
visible: true
Component.onCompleted: console.log("mainWindow width: " + width)
Item {
id: topLevelItem
anchors.fill: parent
onWidthChanged: print("topLevelItem width: " + width)
Component.onCompleted: console.log("topLevelItem width: " + width)
}
}
输出:
qml: topLevelItem width: 0
qml: mainWindow width: 1024
qml: topLevelItem width: 1024
我不确定到底发生了什么,但很可能窗口首先得到它的大小,然后告诉contentItem
,它可以开始布置它的项目并给出它们的大小。这是异步发生的,这也是为什么在某些情况下不应该依赖命令式代码的原因之一
还值得指出的是,在使用布局时,您可以同时拥有像素完美的项目和可调整大小的项目;使用例如
Layout.minimumWidth
和Layout.maximumWidth
来强制某些大小。我知道没有严格的评估顺序来尊重声明顺序,但我认为只有在项目完全呈现后才会调用onCompleted
。这似乎是我的错误。我知道没有严格的评估顺序来尊重声明顺序,但我认为只有在项目完全呈现后才会调用onCompleted
。看来这是我的错误。