在 QtQuick2 中通过 QML 显示 C++ class
Displaying a C++ class via QML in QtQuick2
我正在开发 QtQuick 2 应用程序(Qt 版本 6.2.3)。我创建了一个 C++ class(我们称之为 class“示例”),其中包含我的应用程序应处理的数据。这个class可以多次实例化,代表不同的数据集显示。
class ExampleObject : public QObject {
Q_OBJECT
Q_PROPERTY(QString property1 MEMBER property1 CONSTANT)
...
public:
QString property1;
};
Q_DECLARE_METATYPE(ExampleObject*)
我希望能够通过 QML 显示此 class 的实例,因此我创建了一个“示例”自定义组件,其中 属性 指向包含我想要的数据的示例 C++ 对象显示。
ExampleComponent {
property var exampleCppObject // exampleCppObject is a pointer to an instance of ExampleObject
Label {
text: exampleCppObject.property1
}
}
为了能够更改 QML 组件使用的示例实例,我创建了函数来“重新初始化”和“更新”组件:
ExampleComponent {
property var exampleCppObject // exampleCppObject is a pointer to an instance of ExampleObject
property string textToDisplay
function update() {
textToDisplay=Qt.binding(() => exampleCppObject.property1);
}
function reinitialize() {
textToDisplay=""
}
Label {
text: textToDisplay
}
}
我在更改或删除 ExampleCppObject 指向的 Example 对象后调用了这些函数,这工作得很好。但我觉得这不是最佳做法,在我看来我做错了。
在我描述的情况下,将 C++ 连接到 QML 的更好方法是什么?
编辑:我的 main.cpp 主要包括:
MainModel mainModel;
QQmlApplicationEngine engine;
engine.rootContext()->setContextProperty("mainModel", &mainModel);
engine.load(QStringLiteral("qrc:/main.qml"));
其中 mainModel 是一个对象,它可以在应用程序处于 运行 时创建不同的 ExampleObject 实例。
您可以优化绑定 textToDisplay
,这样您就不必调用 upate
和 reinitialize
函数,这似乎是您要解决的问题:
property var exampleCppObject
property string textToDisplay : exampleCppObject ? exampleCppObject.property1 : ""
如果以后需要更复杂的逻辑,也可以使用大括号:
property string textToDisplay: {
console.log("log me everytime the binding is reevalutated")
if(condition1)
return "invalid"
else if(condition2)
return exampleCppObject.property2
else
return exampleCppObject.property1
}
其中最好的部分是,QQmlEngine 实际上会重新评估此绑定中使用的每个 属性 的绑定(具有通知信号),因此如果制作正确,您可以在很大程度上保留绑定单独(意味着你不需要 update
和 reinitialize
函数)
我正在开发 QtQuick 2 应用程序(Qt 版本 6.2.3)。我创建了一个 C++ class(我们称之为 class“示例”),其中包含我的应用程序应处理的数据。这个class可以多次实例化,代表不同的数据集显示。
class ExampleObject : public QObject {
Q_OBJECT
Q_PROPERTY(QString property1 MEMBER property1 CONSTANT)
...
public:
QString property1;
};
Q_DECLARE_METATYPE(ExampleObject*)
我希望能够通过 QML 显示此 class 的实例,因此我创建了一个“示例”自定义组件,其中 属性 指向包含我想要的数据的示例 C++ 对象显示。
ExampleComponent {
property var exampleCppObject // exampleCppObject is a pointer to an instance of ExampleObject
Label {
text: exampleCppObject.property1
}
}
为了能够更改 QML 组件使用的示例实例,我创建了函数来“重新初始化”和“更新”组件:
ExampleComponent {
property var exampleCppObject // exampleCppObject is a pointer to an instance of ExampleObject
property string textToDisplay
function update() {
textToDisplay=Qt.binding(() => exampleCppObject.property1);
}
function reinitialize() {
textToDisplay=""
}
Label {
text: textToDisplay
}
}
我在更改或删除 ExampleCppObject 指向的 Example 对象后调用了这些函数,这工作得很好。但我觉得这不是最佳做法,在我看来我做错了。
在我描述的情况下,将 C++ 连接到 QML 的更好方法是什么?
编辑:我的 main.cpp 主要包括:
MainModel mainModel;
QQmlApplicationEngine engine;
engine.rootContext()->setContextProperty("mainModel", &mainModel);
engine.load(QStringLiteral("qrc:/main.qml"));
其中 mainModel 是一个对象,它可以在应用程序处于 运行 时创建不同的 ExampleObject 实例。
您可以优化绑定 textToDisplay
,这样您就不必调用 upate
和 reinitialize
函数,这似乎是您要解决的问题:
property var exampleCppObject
property string textToDisplay : exampleCppObject ? exampleCppObject.property1 : ""
如果以后需要更复杂的逻辑,也可以使用大括号:
property string textToDisplay: {
console.log("log me everytime the binding is reevalutated")
if(condition1)
return "invalid"
else if(condition2)
return exampleCppObject.property2
else
return exampleCppObject.property1
}
其中最好的部分是,QQmlEngine 实际上会重新评估此绑定中使用的每个 属性 的绑定(具有通知信号),因此如果制作正确,您可以在很大程度上保留绑定单独(意味着你不需要 update
和 reinitialize
函数)