Displaying a C++ class via QML in QtQuick2
-
I am working on a QtQuick 2 application (Qt version 6.2.3). I created one C++ class (let's call this class "Example") that contains the data that my application should deal with. This class can be instantiated several times, representing different datasets to be displayed.
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.
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:
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. 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?
Many thanks in advance! -
@emyrcatsor said in Displaying a C++ class via QML in QtQuick2:
ExampleObject
The easiest way is something like this:
Q_PROPERTY(QString myProperty READ getMyProperty WRITE setMyProperty NOTIFY myPropertyChanged)
public: QString getMyProperty(); void setMyProperty(const QString &myProperty); signals: void myPropertyChanged();
In QML you can access the property by its name. if you update the value on the QML side, it automatically uses the WRITE method to update the c++ object. as long as you emit the NOTIFY signal when updating the objects property, the object will be re-evaluated automatically in QML. (as well as all bindings to this object)
Also you can use a wrapper class to easily access your objects in QML and pass it as a context property to QML:
// main.cpp WrapperClass wc; engine.rootContext()->setContextProperty("WRAPPER", &wc);
class WrapperClass : public QObject { Q_OBJECT Q_PROPERTY(QList<ExampleObject *> myObjects READ getMyObjects NOTIFY myObjectsChanged) public: explicit WrapperClass(QObject *parent = nullptr); QList<ExampleObject *> getMyObjects();
then you can use it in QML e.g. like this:
ListView{ // WRAPPER is defined as context property in main.cpp // myObjects uses the READ method of the the WrapperClass object which returns QList<ExampleObject *> model: WRAPPER.myObjects delegate: TextField{ // modelData = model[index] = current object // myProperty uses the READ method of your object (ExampleObject) to read its value text: modelData.myProperty onAccepted: { // update the property using the WRITE method of the object modelData.myProperty = text } } }
-
Thanks so much, that is indeed what I ended with!
-