我可以为像组件这样的所有属性创建自己的附件吗?
Item{
Component.onCompleted : {} // Component is attached to everyone Items
}
您可能无法将属性附加到您未创建的项目或组件。但是你为什么要这样做呢?
相反,您可以考虑使用信号和全局属性。
对于可以从任何地方访问的全局属性,您可以设置声明性视图的根上下文的上下文属性。
IE,
QmlApplicationViewer viewer;
MyPropertyClass myProp;
viewer->rootContext()->setContextProperty("MyPropClass", &myProp);
现在,在您的 QML 文件中,您可以访问此类的属性
Rectangle {
Text {
text: MyPropClass.getMyPropText()
}
MouseArea {
onClicked: { MyPropClass.text = "Clicked" }
}
}
这将从 MyPropertyClass 调用 Q_INVOKABLE 方法 getMyPropText()。并且 Q_PROPERTY 'text' 可以在发出某些信号时设置。
你需要这件衣服吗?
是的,例如:
#include <QQmlEngine>
#include <QTimer>
class TestAttached : public QObject
{
Q_OBJECT
// Declare property with setter and getter
Q_PROPERTY(int val READ getVal WRITE setVal)
public:
TestAttached() Q_DECL_EQ_DEFAULT;
explicit TestAttached(QObject *parent):
QObject{parent},
m_val{100500}
{
Q_ASSERT(parent);
qDebug() << "* We just have created the object of attached properties for" << parent->metaObject()->className();
}
~TestAttached() Q_DECL_EQ_DEFAULT;
// define static function qmlAttachedProperties(QObject *object)
// which returns pointer to instance of TestAttached class
static TestAttached *qmlAttachedProperties(QObject *object)
{
TestAttached* testAttached { new TestAttached{object} };
QTimer* timer { new QTimer{testAttached} };
connect(timer, &QTimer::timeout,
[testAttached] {
testAttached->setVal(testAttached->getVal()+1);
emit testAttached->testDone(testAttached->getVal());
});
timer->start(3000);
return testAttached;
}
inline int getVal() const
{
return m_val;
}
inline void setVal(int val)
{
m_val = val;
}
signals:
void testDone(int val);
private:
int m_val;
};
// Makes the type TestAttached known to QMetaType (for using with QVariant)
QML_DECLARE_TYPE(TestAttached)
// declares that the TestAttached supports attached properties.
QML_DECLARE_TYPEINFO(TestAttached, QML_HAS_ATTACHED_PROPERTIES)
在 QML 系统中注册附加类型(例如 at main.cpp
):
qmlRegisterUncreatableType<TestAttached>("my.test", 1, 0, "Test", QObject::tr("Test is an abstract type that is only available as an attached property."));
并尝试main.qml
:
import QtQuick 2.15
import QtQuick.Window 2.15
//import our module
import my.test 1.0
Window {
width: 640
height: 480
visible: true
title: qsTr("Hello World of Attached properties")
Rectangle {
color: focus ? Qt.lighter("red") : "red"
width: parent.width/2; height: parent.height
anchors.left: parent.left
Component.onCompleted: {
console.log("Rectangle is completed", Test.val)
}
Keys.onReturnPressed: {
console.log("Rect 1: Attachet value is", Test.val)
}
Test.val: 20000
Test.onTestDone: function(num) {
console.log("We received", num, "from attached object")
}
MouseArea {
anchors.fill: parent
onClicked: parent.focus = true
}
}
Rectangle {
color: focus ? Qt.lighter("blue") : "blue"
width: parent.width/2; height: parent.height
anchors.right: parent.right
focus: true
Keys.onReturnPressed: {
// The attached object will created after return pressed
console.log("Rect 2: Attachet value is", Test.val)
}
MouseArea {
anchors.fill: parent
onClicked: parent.focus = true
}
}
}