简体   繁体   English

在 QtQuick2 中通过 QML 显示 C++ class

[英]Displaying a C++ class via QML in QtQuick2

I am working on a QtQuick 2 application (Qt version 6.2.3).我正在开发 QtQuick 2 应用程序(Qt 版本 6.2.3)。 I created one C++ class (let's call this class "Example") that contains the data that my application should deal with.我创建了一个 C++ class(我们称之为 class“示例”),其中包含我的应用程序应处理的数据。 This class can be instantiated several times, representing different datasets to be displayed.这个class可以多次实例化,代表不同的数据集显示。

class ExampleObject : public QObject {
    Q_OBJECT
    Q_PROPERTY(QString property1 MEMBER property1 CONSTANT)
    ...

    public:
    QString property1;
};

Q_DECLARE_METATYPE(ExampleObject*)

I want to be able to display instances of this class via QML, therefore I created a "Example" custom component with a property pointing to the Example C++ object containing the data I want to display.我希望能够通过 QML 显示此 class 的实例,因此我创建了一个“示例”自定义组件,其属性指向包含我要显示的数据的示例 C++ object。

ExampleComponent {
    property var exampleCppObject // exampleCppObject is a pointer to an instance of ExampleObject

    Label {
        text: exampleCppObject.property1
    }
}

To be able to change the Example instance used by the QML component, I created functions to "reinitialize" and "update" the component:为了能够更改 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
    }
}

I call these functions after changing or deleting the Example object pointed by ExampleCppObject, and this works quite fine.我在更改或删除 ExampleCppObject 指向的示例 object 后调用了这些函数,这工作得很好。 But I feel like this isn't best practice, and it seems to me that I am doing things wrong.但我觉得这不是最佳做法,而且在我看来我做错了。

What are better ways of connecting C++ to QML, in the situation I described?在我描述的情况下,将 C++ 连接到 QML 有哪些更好的方法?


Edit: my main.cpp essentially consists in:编辑:我的 main.cpp 主要包括:

MainModel mainModel;
QQmlApplicationEngine engine;
engine.rootContext()->setContextProperty("mainModel", &mainModel);
engine.load(QStringLiteral("qrc:/main.qml"));

Where mainModel is an object which can create different instances of ExampleObject while the application is running.其中 mainModel 是一个 object,它可以在应用程序运行时创建不同的 ExampleObject 实例。

You can optimize the binding textToDisplay such that you don't have to call the upate and reinitialize functions, which seems to be the question you are after:您可以优化绑定textToDisplay ,这样您就不必调用upatereinitialize函数,这似乎是您要解决的问题:

property var exampleCppObject
property string textToDisplay : exampleCppObject ? exampleCppObject.property1 : ""

In case you need more complex logic in the future, you can also use braces:如果您将来需要更复杂的逻辑,您还可以使用大括号:

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
}

The best part of this, is that QQmlEngine actually reevaluates the binding for every property that is used in this binding (which has a notify signal), so if crafted correctly, you can largely leave the binding alone (meaning you don't need the update and reinitialize function)最好的部分是,QQmlEngine 实际上会重新评估此绑定中使用的每个属性的绑定(它有一个通知信号),因此如果制作正确,您可以在很大程度上单独保留绑定(意味着您不需要updatereinitialize函数)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM