Flickable + property alias contents

1.2k views Asked by At

I've noticed a strange behavior with inheriting Flickable.

I have two files, Comp.qml and main.qml. The idea is that any children of a Comp object will be children of the Flickable under Comp. I've defaulted the contents using

default property alias contents: flickable.children

but the results turn out to be strange.

Comp.qml

Rectangle {
    id: comp;
    anchors.fill: parent

    default property alias contents: flickable.children;  // alias a default property
    property int contentHeight: comp.height;

    Flickable {
        id: flickable;
        anchors.fill: parent;
        contentHeight: comp.contentHeight;
    }
}

main.qml

Rectangle {
    id: root;
    width: 400;
    height: 400;

    Comp {
        contentHeight: 800;


        Rectangle {         //  <-- this rectangle should be a child of Flickable
            width: 800;
            height: 800;
            border.color: "black";
            border.width: 5;
            Component.onCompleted: console.debug(parent)
        }
    }
}

The flickable doesn't work.

If I try to put it all in one file, it work as expected :

main.qml

Rectangle {
    id: root;
    width: 400;
    height: 400;

    Rectangle {
        id: comp;
        anchors.fill: parent

        Flickable {
            id: flickable;
            anchors.fill: parent;
            contentHeight: 800;

            Rectangle {   //   <-- the child component
                width: 800;
                height: 800;
                border.color: "black";
                border.width: 5;
            }
        }
    }
}

Am I missing something? How do I add an external component into a Flickable?

1

There are 1 answers

0
BaCaRoZzo On BEST ANSWER

As stated in the docs:

Items declared as children of a Flickable are automatically parented to the Flickable's contentItem. Items created dynamically need to be explicitly parented to the contentItem

That's not the first case here, i.e. the Rectangle got parented to the Flickable itself and does not expose the expected behaviour. Possibly, the addition to the children does not trigger the correct parenting, in this case. As a quick fix you can re-parent the item as soon as it is added to the Comp type.

To handle multiple Items inside your Comp just use a unique child (a la ScrollView). Here I modified the example to handle two Rectangles (just added clip to Comp, for aesthetic purposes).

In the main:

Rectangle {
    id: root;
    width: 400;
    height: 400;

    Comp {
        contentHeight: col.height;

        Column {
            id: col
            spacing: 20
            Rectangle {
                width: 800;
                height: 800;
                border.color: "black";
                border.width: 5;
            }

            Rectangle {
                width: 800;
                height: 800;
                border.color: "black";
                border.width: 5;
            }
        }

        Component.onCompleted: console.debug(col.parent) // <-- not flickable
    }
}

In the Comp.qml file:

Rectangle {
    id: comp;
    anchors.fill: parent
    default property alias contents: flickable.children;
    property int contentHeight: comp.height;

    Flickable {
        z:1
        clip: true       // just my taste!
        id: flickable;
        anchors.fill: parent;
        contentHeight: comp.contentHeight;
    }

    onContentsChanged: {                             // re-parenting
        if(flickable.children[1] !== undefined)
            flickable.children[1].parent = flickable.contentItem
    }
}