在 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,这样您就不必调用 upatereinitialize 函数,这似乎是您要解决的问题:

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 实际上会重新评估此绑定中使用的每个 属性 的绑定(具有通知信号),因此如果制作正确,您可以在很大程度上保留绑定单独(意味着你不需要 updatereinitialize 函数)