Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

setContextProperty : integrating c++ with qml



  • Hi all ,
    i am using Q_Property and setContextProperty to capture changes in C++ class variable into Qml file.
    Qt 5.12, Linux + Windows

    problem statement : i dont want to call "setContextProperty" for every object created.
    if i have to monitor 20 object it leads me to call "setContextProperty" 20 times.

    any wy that i capture c++ object in qml , apart from using setContext property, cant proceed with singletone approach or qml registertype.

    any other good practice to achieve the same.

    // tempraturegugage.h
    
    #include <QObject>
    
    class TempratureGuage : public QObject
    {
        Q_OBJECT
        Q_PROPERTY(int temprature READ temprature WRITE setTemprature NOTIFY tempratureChanged)
    
    public:
        TempratureGuage();
    
        void setTemprature(const int &t) {
            if (t != m_temprature) {
                m_temprature = t;
                emit tempratureChanged();
            }
        }
        int temprature() const {
            return m_temprature;
        }
    signals:
        void tempratureChanged();
    private:
        int m_temprature;
    };
    
    // tempratureguage.cpp
    
    #include "tempratureguage.h"
    
    TempratureGuage::TempratureGuage()
        : m_temprature(0)
    {
    }
    
    // main.cpp
    #include <QGuiApplication>
    #include <QQmlApplicationEngine>
    #include <QQmlContext>
    #include "tempratureguage.h"
    
    int main(int argc, char *argv[])
    {
    #if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
        QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
    #endif
    
        QGuiApplication app(argc, argv);
    
        QQmlApplicationEngine engine;
    
        QQmlContext* context = new QQmlContext(engine.rootContext());
    
    // problem statement : i dont want to use setContext property for every object i created.
        TempratureGuage obj1;
        context->setContextProperty("obj1", &obj1);
    
        TempratureGuage obj2;
        context->setContextProperty("obj2", &obj2);
    
        TempratureGuage obj3;
        context->setContextProperty("obj3", &obj3);
    
        const QUrl url(QStringLiteral("qrc:/main.qml"));
        QObject::connect(&engine, &QQmlApplicationEngine::objectCreated,
                         &app, [url](QObject *obj, const QUrl &objUrl) {
            if (!obj && url == objUrl)
                QCoreApplication::exit(-1);
        }, Qt::QueuedConnection);
        engine.load(url);
    
        return app.exec();
    }
    
    
    //// main.qml
    
    import QtQuick 2.12
    import QtQuick.Window 2.12
    import QtQuick.Layouts 1.15
    
    
    Window {
        id : root
        width: 640
        height: 480
        visible: true
        title: qsTr("Hello World")
    
        property int  temp1: obj1.tempratureChanged
        property int  temp2: obj2.tempratureChanged
        property int  temp3: obj3.tempratureChanged
    
        ColumnLayout{
            spacing: 2
    
            Rectangle {
                Text {
                    id: t1
                    text:root.temp1
                }
            }
    
            Rectangle {
                Text {
                    id: t2
                    text: root.temp2
                }
            }
    
            Rectangle {
                Text {
                    id: t3
                    text: root.temp3
                }
            }
        }
    }
    
    


  • @Anas_Deshmukh

    If you don't want to export object by object then use a qml registertype and then create the objects in QML. setContextProperty is one of the many options that Qt offers for a good integration between C ++ and QML, it will depend on your requirements if you choose one or the other, read https://doc.qt.io/qt-5/qtqml-cppintegration-overview.html.



  • @eyllanesc creating object in qml is not suitable to my application at this moment.



  • @Anas_Deshmukh

    If your reason for not creating them in QML is that you want a handle to the objects. You could always pass them back to your C++ code though an Q_INVOCABLE method. Consider:

    Controller : public QObject
    {
    Q_INVOKABLE void addGuage(TempGauge *);

    private:
    QVector<TemperatureGauge *> m_gauges;
    };


Log in to reply