Qml属性挂钩

Qml property hooks

本文关键字:属性 Qml      更新时间:2023-10-16

假设有一个名为Test的Qml类型具有foo属性,它的实现如下:Test.qml

// Not necessarily QtObject, but derived from QObject
QtObject {
    // Not necessarily var/property, but must behave like property (i.e. be accessible using "<instance>.foo")
    property var foo
}

并以以下方式使用:main.qml

import "."
Test {
    id: _test
}
function baz() {
    var x = _test.foo;
    _test.foo = x;
}

我想要的是每次getter或setter访问foo属性时都得到通知。对于setter,也许我可以使用fooChanged信号,但对于getter,并没有这样的解决方案。此外,我可以用Q_PROPERTY宏将Test类型实现为C++类,并从属性getter/setter中发出相应的信号,但我真的想把大部分代码留在Qml端。

是否有其他方法可以挂接Qml属性访问?

好吧,经过几个小时的谷歌搜索,阅读了Qml和JS文档,我想我终于找到了解决方案。它涉及一些技巧,因为JS在Qml中不完全支持,但这个解决方案仍然有效。其主要思想是使用JS defineProperty方法来动态地向现有对象添加属性。现在我的Test.qml文件如下:

QtObject {
    // NOTE: .defineProperty does not correctly work for Qml objects, so JS object is used instead
    property var object: { return {}; }
    Component.onCompleted: {
        Object.defineProperty(
            object,
            "foo",
            {
                get: function () {
                    // getter handling here
                },
                set: function (value) {
                    // setter handling here
                }
            }
        );
    }
}

main.qml中,_test实例声明如下:

property alias _test: _testDeclaration.object
Test {
    id: _testDeclaration
}

希望这个答案能帮助其他人。