How to create grouped/nested properties?

人盡茶涼 提交于 2019-12-30 03:23:07

问题


I am trying to do nested properties like 'font.family' or 'anchors.fill', but I cannot initialize them in normal way because it prints 'Cannot assign to non-existent property'. Instead I am forced to use Component.onCompleted method. What's wrong?

MyButtonStyling.qml:

import QtQml 2.1

QtObject
{
    property QtObject background: QtObject
    {
        property color pressed: "#CCCCCC"
        property color enabled: "#666666"
        property color disabled: "#555555"
    }
}

main.qml:

import QtQuick 2.0

Item
{
    width: 400
    height: 300
    MyButton
    {
        text: "TEST"
        styling: MyButtonStyling
        {
            //background.enabled: "#1B2E0A" //Cannot assign to non-existent property "enabled"
            Component.onCompleted:
            {
                background.enabled = "#1B2E0A" //Works
            }
        }
    }
}

MyButton.qml:

import QtQuick 2.0
import QtQuick.Controls 1.0
import QtQuick.Controls.Styles 1.0

Button
{
    property QtObject styling: MyButtonStyling {}

    implicitWidth: 80
    implicitHeight: 80

    style: ButtonStyle
    {
        background: Item
        {
            Rectangle
            {
                anchors.fill: parent
                color: control.pressed ? styling.background.pressed : control.enabled ? styling.background.enabled : styling.background.disabled
            }
        }
    }
}

回答1:


Try replacing your nested QtObject with a QML file. For example, I replaced it with BackgroundTheme.qml. This way, the property (which can correcly be called "grouped property") works correctly, in a binding and without any error.

BackgroundTheme.qml

import QtQuick 2.0

QtObject {
  property color pressed: "#CCCCCC"
  property color enabled: "#666666"
  property color disabled: "#555555"
}

MyButtonStyling.qml

import QtQuick 2.0

QtObject {       
    property BackgroundTheme background: BackgroundTheme {}
}



回答2:


To add to the What's wrong part of your question.

Your approach does not work, because left-hand-side expressions are statically typed in QML.

I had the same problem and found this comment by Matthew Vogt to a QT bug report:

This behavior is currently correct.

QML is statically typed for left-hand-side expressions, so dynamic properties not present in the static type of a property cannot be resolved in initialization.

The workaround for this issue is to move the declaration of the type to be initialized to its own file, so that it can be declared as a property with a correct static type.

The previous comment gives a good example:

This bug is not specifically related to the use of the alias - it results from property lookup during compilation in different units. A simple example:

Base.qml

import QtQuick 2.0

Item {
    property QtObject foo: Image {
        property color fg: "red"
    }

    property color bar: foo.fg
}

main.qml

import QtQuick 2.0

Base {
    foo.fg: "green"
}

Here, 'foo' has the static type 'QtObject' and the dynamic type 'QQuickImage_QML_1'. The lookup of 'fg' is successful in the initialization of 'bar' inside Base.qml, but fails in main.qml.




回答3:


This may not be the right way. But this works

MyButtonStyling.qml

import QtQml 2.1

QtObject
{
    property alias background: _obj_background

    QtObject 
    {
        id: _obj_background
        property color pressed: "#CCCCCC"
        property color enabled: "#666666"
        property color disabled: "#555555"
    }
}

Now using background.enabled: "#1B2E0A" in main.qml works.



来源:https://stackoverflow.com/questions/28169655/how-to-create-grouped-nested-properties

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!