我正在尝试执行“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
}
}
}
}
尝试用 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 {}
}
添加到问题的“出了什么问题”部分。 您的方法不起作用,因为
左侧表达式在 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 中查找失败。
这可能不是正确的方法。但这有效
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"
}
}
background.enabled: "#1B2E0A"
可以工作。更现代的方法是利用 Qt 5.15
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 {}
}