qt - QML 列:可能的 QQuickItem::polish() 循环

标签 qt qml

以下代码有两个问题。

  1. 如果我在 QML 列中使用填充,我会收到以下消息:

    QML Column: possible QQuickItem::polish() loop
    

    并且应用程序变得无响应。另外,如果我不使用 anchor ,则不会出现问题,但列内的矩形不会被拉伸(stretch)。

  2. 如果我使用 anchor ,列的隐式宽度和隐式高度将为零,这将导致矩形不会显示。

Qt 文档是这样说的:

Also, since a Column automatically positions its children vertically, a child item within a Column should not set its y position or vertically anchor itself using the top, bottom, anchors.verticalCenter, fill or centerIn anchors.

这意味着不禁止水平锚定(左/右)。

知道可能出了什么问题吗?

Rectangle {
    anchors.fill: parent
    color: "green"
    Rectangle {
        anchors.centerIn: parent
        implicitWidth: col.implicitWidth
        implicitHeight: col.implicitHeight
        color: "blue"
        Column {
            spacing: 10
            //padding: 10 // causes: QML Column: possible QQuickItem::polish() loop
            id: col
            Rectangle {
                anchors.left: parent.left
                anchors.right: parent.right
                implicitWidth: 100
                implicitHeight: 25
            }
            Rectangle {
                //anchors.left: parent.left // uncommenting these anchors will result that the column's implicitWidth and implicitHeight will be 0
                //anchors.right: parent.right
                implicitWidth: 200
                implicitHeight: 25
            }
            Component.onCompleted: console.log("column, imp width: " + implicitWidth + ", imp height: " + implicitHeight)
        }
    }
}

最佳答案

正如评论中所讨论的,Ponzifex 的代码可以改进:

删除重定父级并创建一个新的默认属性别名,如下所示:

Rectangle 
{ 
   default property alias data2: col.data

   data: 
   [ 
      Column 
      { 
        id: col; 
        onChildrenChanged: { ...calculate sizes, add bindings, etc... }
      } 
   ]
} 

这是如何工作的:

  • 当在 QML 代码中将对象嵌套在另一个对象中时,您将它们添加到父对象内标记为 default 的属性
  • 对于 Item 以及 Rectangle,名为 data 的属性被标记为 default
    • 该属性包含 Item/Rectangle 的可视子项和资源的组合列表
    • 因此,通常在 Rectangle 中嵌套视觉元素会导致它们被添加为 Rectangle 的视觉子元素
    • 通常 矩形 { Text {};计时器{} } ...
    • ...相当于:矩形 { data: [ Text {}, Timer{} ] }
  • 我通过创建一个名为 data2 的新属性并将其设置为 Rectangledefault 来更改这一点
    • data2data 无关,因此它的元素不会添加到 Rectangle 的可视子级列表
    • 相反,我将 data2 设为 Columndata 属性的别名
    • alias 属性就是 - 别名 - 属性的另一个名称,在本例中 - 作为另一个对象的属性 - 但两个名称都“指向”同一个实际属性,因此的视觉子级列表
    • 因此,嵌套在 Rectangle 内的所有 QML 元素都将添加为 Column 的可视子元素
  • 但是,现在我遇到了一个问题:我不能在 QML 代码中将 Column 嵌套到 Rectangle 中,因为这意味着 Column需要添加为它自己的 child (这没有意义)
    • 因此,我必须分配 Rectangle 的实际 data 属性(该属性不再是默认值,因此我必须明确写入其名称),从而添加 Column 作为矩形的可视子级
  • 现在,每当添加或删除 Rectangle 的嵌套元素(包括通过 Repeater)时,Column 数据 属性发生变化,但由于我们添加了可视子元素,children 属性也会发生变化
    • 因此,当ColumnonChildrenChanged信号触发时,我们可以触发重新计算和重新绑定(bind)(如果您还想在非特定情况下触发,则触发onDataChanged)视觉 child 又名资源)
    • 您可以跳过已绑定(bind)的元素或重新绑定(bind)它们

据我所知,这应该是有效且受支持的 QML 语法 - 只是不是您通常使用的语法 - 因此可以在生产代码中使用它,也许可以用注释解释正在发生的情况

关于qt - QML 列:可能的 QQuickItem::polish() 循环,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66303743/

相关文章:

c++ - 如何保证通过QNetworkAccessManager下载的文件没有损坏?

c++ - Qt:将 C++ 类暴露给 QML 时出错

qt - Visual C# 中的 Gtk 尝试了一切。我将无法开发跨平台应用程序吗?

qt - 如何访问其他 QML 文件中的 "ApplicationWindow"引用?

c++ - Qt:如何使半透明、无窗口、无边框的窗口可拖动?

c++ - Qt 和 C++ : app crashes only in debug mode

c++ - 当底层模型发生变化时,如何在 QTableView 中禁用自动滚动到顶部?

c++ - 如何使 OpenGL 视口(viewport)具有渲染到其中的 QML 项目的确切大小和位置?

qt - QML:如何动态添加行

javascript - 如何使用QML相机捕获用户定义尺寸的图像