fallerd
fallerd

Reputation: 1738

Custom properties don't exist at compile time? "Cannot assign to non-existent property"

In referencing an item's properties from outside its parent component, I can get a "Cannot assign to non-existent property" error that seems to depend on some compile time order-of-operations.

I have created a small example app that shows some various ways to assign a color to this property, where direct assignment fails, but similar assignment to default properties works, or even later assignment works.

Here is my main.qml:

import QtQuick 2.7
import QtQuick.Window 2.12

Window {
    id: application_window
    visible: true
    width: 640
    height: 480

    Thing {
//        colors.backgroundColor: "red"  // Direct assignment of custom property: Fails
//        thing.color: "red"           // Direct assignment of default property: Works
//        Component.onCompleted: colors.backgroundColor = "red"  // Run time assignment of custom property: Works
    }
}

and a file called Thing.qml in the same dir:


Item {
    id: root
    height: 50
    width: 50
    property alias colors: colors
    property alias thing: thing

    Rectangle {
        id: thing
        anchors.fill: root
        color: colors.backgroundColor
    }

    Item {
        id: colors
        property color backgroundColor: "blue"
    }
}

By individually uncommenting the lines in main.qml, you can see that directly assigning colors.backgroundColor does not work, but the other ways of changing the color do work, even assigning colors.backgroundColor at runtime. I have also moved the 'colors' Item to a different file, which allows direct assignment (I guess the backgroundColor becomes considered like a default property in this case). Is there any way to directly assign the colors.background color without a separate file or waiting until runtime?

Upvotes: 2

Views: 602

Answers (1)

GrecKo
GrecKo

Reputation: 7170

Is there any way to directly assign the colors.background color without a separate file or waiting until runtime?

No.

When you are declaratively setting (using it in the left hand side of a binding) a sub property (property of a grouped property) like foo.bar, the QML engine can only do so if the type of foo has a bar property.

In your example when doing thing.color, thing's type is Rectangle so it does have a color property. When doing colors.backgroundColor, I guess the type of colors is Item and not the implicit type defined in Thing.qml.

When you are creating a 'colors' Item in a different file, the QML engine is aware of the explicit type of the object and the binding then works.

One could argue that the engine could use the implicit type for the alias property, but I'm not sure if it's the correct way, you are essentially exposing an inline implementation detail to the outside.

You could alway open a bug about that, at least to clarify things even if the behaviour is not changed.

Upvotes: 2

Related Questions