关于Qml的Window控件不能使用id进行布局定位的问题

解决Qml的Window控件不能使用id进行布局定位的问题。

问题重现

  • 运行后Rectangle并不能按照预想的置于底部行为,而是布局不变(默认布局顶部)。
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    Window {
    id: root
    visible: true
    width: 640
    height: 480

    Rectangle {
    id: rect
    width: 100; height: 100
    anchors.bottom: root.bottom
    color: "red"
    }
    }

分析

  • 先查看Qt官方文档找找线索,既然布局不了就找anchors布局的文档,通过全局搜索文档找到了以下信息。

    1
    2
    Note: You can only anchor an item to siblings or a parent. 
    注意:只能将项目锚定到同级或父级。
  • 由此可以推测Window的rootid所指向的并不是派生于Item(或QQuickItem)的。

  • 通过打印Window的id与parent属性分别为QQuickWindowQmlImpl与QQuickRootItem,可以肯定的是QQuickWindowQmlImpl不是继承于QQuickItem,导致布局不到的问题。
  • 感觉那里不对,又找了下文档,看到以下信息:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    [default] data : list<Object>

    The data property allows you to freely mix visual children, resources and other Windows in a Window.
    If you assign another Window to the data list, the nested window will become "transient for" the outer Window.
    If you assign an Item to the data list, it becomes a child of the Window's contentItem, so that it appears inside the window. The item's parent will be the window's contentItem, which is the root of the Item ownership tree within that Window.
    If you assign any other object type, it is added as a resource.
    It should not generally be necessary to refer to the data property, as it is the default property for Window and thus all child items are automatically assigned to this property.

    data属性允许您在Window中自由混合可视子项,资源和其他Windows。
    如果将另一个窗口分配给数据列表,嵌套窗口将变为"瞬态"外部窗口。
    如果将一个Item分配给数据列表,它将成为Window的contentItem的子项,以便它出现在窗口内。 项目的父项将是窗口的contentItem,它是该窗口中项目所有权树的根。
    如果指定任何其他对象类型,则将其添加为资源。
    通常不需要引用data属性,因为它是Window的默认属性,因此所有子项都会自动分配给此属性。
  • 大概意思是Window窗口的根Item被附加在contentItem上。

解决方法

  • 使用parentroot.contentItemWindow.contentItem替换root作为布局的锚。