4
votes

Qt/QML question. Using Qt 5.7.

Take the following simple QML program that displays a red rectangle and a blue rectangle aligned vertically. Click handlers for both rectangles attempt to change the color of the parent host window. But with a subtle difference. The red rectangle references the host window directly by it's id (rootWindow). The blue click handler changes color via a parent reference.

The former case works fine. The latter case does not work. It seems like the root window is treated specially and isn't directly part of the parent/child hierarchy, even if the Rectangles are logically nested in the code that way.

Can someone explain the rule around this?

import QtQuick 2.7
import QtQuick.Window 2.2

Window {
    visible: true
    width: 640
    height: 480
    title: qsTr("Hello World")
    id: rootWindow
    color: "#ffffee"

    Rectangle {
        id: rect1; width: 50; height: 50; color:"red"

        MouseArea {
            anchors.fill: parent;
            onClicked: {
                print("rect1 clicked");
                rootWindow.color = "green";  // works fine
            }
        }
    }

    Rectangle {
        id: rect2; width: 50; height: 50; color:"blue"
        anchors.top: rect1.bottom

        MouseArea {
            anchors.fill: parent;
            onClicked: {
                print("rect2 clicked");
                rect2.parent.color = "pink";  // does not work
            }
        }
    }
}
1

1 Answers

5
votes

If you add the following line to the onClicked handler, you'll see that its parent isn't the Window:

print(rect2.parent)

Output:

qml: QQuickRootItem(0x18b18147bc0)

This is explained not-so-visibly in the documentation for 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.

The window itself isn't an item, so it uses contentItem instead so that child items can have a parent.

However, in Qt 5.7, Window got an attached property that can be used to access the window of an item:

rect2.Window.window.color = "pink";

Whichever item comes before the Window.window part will be the item that the attached property is used on. You could use it on any item in this scene (e.g. the MouseArea), as they all belong to the same window.

Note that attached properties create a QObject-derived object for each unique item they're used on, so be mindful of how you use them, especially in items that are created in very large numbers.