QML read and set property within SplitHandle from SplitView

108 views Asked by At

In the following example, how can I read and set the property dummy in rect1 and rect2? I am not sure how to read a property from a loaded component in this case.

import QtQuick 2.15
import QtQuick.Controls 2.15

SplitView {
    id: splitView
    anchors.fill: parent

    handle: Rectangle {
        id: handleRect
        property bool dummy: false
        implicitWidth: 4
        implicitHeight: 4
        color: SplitHandle.pressed ? "#81e889"
            : (SplitHandle.hovered ? Qt.lighter("#c2f4c6", 1.1) : "#c2f4c6")

        Rectangle: {
          visible: dummy
          ...
        }
    }

    Rectangle {
        id: rect1
        implicitWidth: 150
        color: "#444"
        Component.onCompleted: {
            handleRect.dummy = true // Does not work
        }
    }

    Rectangle {
        id: rect2
        implicitWidth: 50
        color: "#666"
    }
}

Using handleRect.dummy within either rect1 or 2 does not work due to TypeError: Cannot read property 'dummy' of undefined.

2

There are 2 answers

0
smr On BEST ANSWER

Continued from the comments.

To access each handle of a SplitView separately, you can use its children property. The handles are accessed starting from the second child (splitView.children[1]), as the first child is a QQuickContentItem containing the Items (splitView.children[0].children).

For the following QML code:

SplitView {
    id: splitView
    anchors.fill: parent

    handle: Rectangle { implicitWidth: 2; color: 'black' }

    Item { implicitWidth: 50; color: 'green' }
    Item { implicitWidth: 50; color: 'white' }
    Item { implicitWidth: 50; color: 'red' }
}

We can use the JavaScript function below:

function getHandleAt(index: int) {
    return splitView.children[index + 1];
}

The handles are accessed starting from the second child, as the first child is the QQuickContentItem containing the Items.

1
Stephen Quan On

Because you could never be guaranteed of the order, you cannot say that the SplitView.handle will exist before your SplitView children. Therefore, the code in Component.onCompleted could not be guaranteed to work.

Instead, if you were to bubble up your property, e.g.

SplitView {
    id: splitView
    property bool dummy: false
    handle: Rectangle { /* ... */ }
    Rectangle { id: rect1 /* ... */ }
    Rectangle { id: rect2 /* ... */ }
}

You can be guaranteed that both SplitView's children and the handle can read/write to it.

You can Try it Online!