如何创建分组/嵌套属性?

问题描述 投票:0回答:4

我正在尝试执行“font.family”或“anchors.fill”等嵌套属性,但我无法以正常方式初始化它们,因为它打印“无法分配给不存在的属性”。相反,我被迫使用 Component.onCompleted 方法。怎么了?

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
            }
        }
    }
}

我的按钮.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
            }
        }
    }
}
qt qml qt5 qt-quick qtquick2
4个回答
13
投票

尝试用 QML 文件替换嵌套的

QtObject
。例如,我将其替换为
BackgroundTheme.qml
。这样,属性(可以正确地称为“分组属性”)在绑定中正常工作,并且没有任何错误。

背景主题.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
投票

添加到问题的“出了什么问题”部分。 您的方法不起作用,因为

左侧表达式在 QML 中是静态类型的。

我遇到了同样的问题,并发现 Matthew Vogt

对 QT 错误报告的评论:

此行为目前是正确的。

QML 的左侧表达式是静态类型的,因此属性的静态类型中不存在的动态属性无法在初始化中解析。

此问题的解决方法是将要初始化的类型的声明移至其自己的文件中,以便可以将其声明为具有正确静态类型的属性。

之前的评论
给出了一个很好的例子:

此错误与别名的使用没有特别关系 - 它是由不同单元中编译期间的属性查找引起的。 一个简单的例子:

基础.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" }

这里,“foo”具有静态类型“QtObject”和动态类型“QQuickImage_QML_1”。在 Base.qml 中初始化 'bar' 时查找 'fg' 成功,但在 main.qml 中查找失败。

这可能不是正确的方法。但这有效

1
投票

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" } }

现在在 main.qml 中使用
background.enabled: "#1B2E0A"
可以工作。


更现代的方法是利用 Qt 5.15

0
投票

Inline Components,这样就无需创建新文件来存储此 QtObject 属性的定义。

内联组件

5.15 中的另一个新功能是内联组件。 顾名思义,它们允许您在内部定义一个新组件 一份文件。基本语法是

component <component name> : BaseType { // declare properties and bindings here }

在文件内,您可以通过名称引用新组件, 就像>就像它是在自己的文件中定义的一样。

MyButtonStyling.qml:

import QtQuick QtObject { component BackgroundTheme: QtObject { property color pressed: "#CCCCCC" property color enabled: "#666666" property color disabled: "#555555" } property BackgroundTheme background: BackgroundTheme {} }


© www.soinside.com 2019 - 2024. All rights reserved.