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

How to update qml text from two different cpp ?



  • I have an qml project.

    There is a text(named id:cnt) on StackPage.qml and I need to update this text from firstclass.cpp and secondclass.cpp.

    Q_PROPERTY defines are on firstclass.h and setCntText function is on firstclass.cpp.

    I update the text from firstclass.cpp by setCntText(i) and try to update from secondclass.cpp by calling setCntText(0).

    I can set the m_cntText variable from secondclass but couldnt update qml text(named id:cnt).

    main.cpp

    #include <QGuiApplication>
    #include <QQmlApplicationEngine>
    #include <QQmlContext>
    
    #include "firstclass.h"
    #include "secondclass.h"
    
    int main(int argc, char *argv[])
    {
        QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
    
        QGuiApplication app(argc, argv);
    
        QQmlApplicationEngine engine;
    
        firstClass frmFirstClass;
        engine.rootContext()->setContextProperty("frmFirstClass",&frmFirstClass);
    
        secondClass frmSecondClass;
    
        engine.load(QUrl(QStringLiteral("qrc:/main.qml")));
        if (engine.rootObjects().isEmpty())
            return -1;
    
        return app.exec();
    }
    

    firstclass.cpp

    #include "firstclass.h"
    
    firstClass::firstClass(QObject *parent) : QObject(parent)
    {
        QTimer *timer1 = new QTimer();
        connect(timer1, &QTimer::timeout, [=]() {setter1();});
        timer1->start(2000);
    }
    
    int firstClass::cntText() const
    {
        return m_cntText;
    }
    
    void firstClass::setCntText(int cntText)
    {
        if (m_cntText == cntText)
            return;
    
        m_cntText = cntText;
        emit cntTextChanged(m_cntText);
    }
    
    void firstClass::setter1()
    {
        static int i = 0;
        i++;
        qDebug() <<"counter1 : " << i;
        setCntText(i);
    }
    

    secondclass.cpp

    #include "secondclass.h"
    
    firstClass frmFirstClass;
    
    secondClass::secondClass(QObject *parent) : QObject(parent)
    {
        QTimer *timer = new QTimer();
        timer->setSingleShot(true);
        timer->start(1000);
    
        connect(timer, &QTimer::timeout, [=]() {
            QTimer *timer2 = new QTimer(this);
            connect(timer2,SIGNAL(timeout()),this,SLOT(setter2()));
            timer2->start(2000);
            timer->deleteLater();
        } );
    }
    
    void secondClass::setter2()
    {
        frmFirstClass.setCntText(0);
        qDebug() << "Checking m_cntText = " << frmFirstClass.m_cntText;
    }
    

    firstclass.h

    #ifndef FIRSTCLASS_H
    #define FIRSTCLASS_H
    
    #include <QObject>
    #include <QTimer>
    #include <QDebug>
    
    class firstClass : public QObject
    {
        Q_OBJECT
        Q_PROPERTY(int cntText READ cntText WRITE setCntText NOTIFY cntTextChanged)
    
    
    public:
        explicit firstClass(QObject *parent = nullptr);
    
        int cntText() const;
    
        int m_cntText;
    
    signals:
    
        void cntTextChanged(int cntText);
    
    public slots:
    
        void setCntText(int cntText);
    
    private slots:
    
        void setter1();
    };
    
    #endif // FIRSTCLASS_H
    

    secondclass.h

    #ifndef SECONDCLASS_H
    #define SECONDCLASS_H
    
    #include <QObject>
    #include <QTimer>
    #include <QDebug>
    #include "firstclass.h"
    
    extern firstClass frmFirstClass;
    
    class secondClass : public QObject
    {
        Q_OBJECT
    
    private:
    
    public:
        explicit secondClass(QObject *parent = nullptr);
    
    signals:
    
    public slots:
    
    private slots:
    
        void setter2();
    };
    
    #endif // SECONDCLASS_H
    

    main.qml

    import QtQuick 2.10
    import QtQuick.Window 2.12
    import QtQuick.Controls 2.0
    
    Window {
        visible: true
        width: 640
        height: 480
        title: qsTr("Hello World")
    
        Rectangle{
            anchors.fill: parent
            color: "black"
    
            StackView{
                anchors.fill: parent
                initialItem : stackPage
            }
    
            Component{
                id:stackPage
                StackPage{}
            }
        }
    }
    

    StackPage.qml

    import QtQuick 2.0
    
    Item {
    
        Rectangle{
            anchors.centerIn: parent
            width: 200
            height: 200
            color: "orange"
    
            Text {
                id: cnt
                text: frmFirstClass.cntText
                verticalAlignment: Text.AlignVCenter
                horizontalAlignment: Text.AlignHCenter
                font.pointSize: 40
                anchors.fill: parent
            }
    
        }
    
    }

  • Lifetime Qt Champion

    @bladekel said in How to update qml text from two different cpp ?:

    firstClass frmFirstClass;

    This is not going to work, as you're using different firstClass instance than the one which is really used (the one created in main()).
    Pass the pointer to firstClass instance to secondClass constructor and use it then.



  • @jsulm said in How to update qml text from two different cpp ?:

    @bladekel said in How to update qml text from two different cpp ?:

    firstClass frmFirstClass;

    This is not going to work, as you're using different firstClass instance than the one which is really used (the one created in main()).
    Pass the pointer to firstClass instance to secondClass constructor and use it then.

    Can you please explain it ? because I dont know how to do it.....


  • Moderators

    @bladekel
    pleas read through this
    http://www.cplusplus.com/doc/tutorial/classes/

    to get a better understanding of what a class and a class instance is



  • @J-Hilk said in How to update qml text from two different cpp ?:

    @bladekel
    pleas read through this
    http://www.cplusplus.com/doc/tutorial/classes/

    to get a better understanding of what a class and a class instance is

    As your suggest, I have read it, and I think I understood what are they.

    But still cant solve my problem...

    Can you please suggest me something more....


  • Moderators

    @bladekel
    ok, now you'll understand that this

    #include "secondclass.h"
    
    firstClass frmFirstClass;
    

    and this

    QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
    
        QGuiApplication app(argc, argv);
    
        QQmlApplicationEngine engine;
    
        firstClass frmFirstClass;
    

    are 2 different instances of firstClass.

    The solution is what @jsulm posted
    modify your 2ndclass constructor to accept, additionally to a parent a pointer to a firstClass instance.

    You should read up on class constructors and pointers, if you're having trouble with this

    https://www.tutorialspoint.com/cplusplus/cpp_constructor_destructor.htm
    https://www.tutorialspoint.com/cplusplus/cpp_pointer_to_class.htm



  • @J-Hilk said in How to update qml text from two different cpp ?:

    @bladekel
    ok, now you'll understand that this

    #include "secondclass.h"
    
    firstClass frmFirstClass;
    

    and this

    QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
    
        QGuiApplication app(argc, argv);
    
        QQmlApplicationEngine engine;
    
        firstClass frmFirstClass;
    

    are 2 different instances of firstClass.

    The solution is what @jsulm posted
    modify your 2ndclass constructor to accept, additionally to a parent a pointer to a firstClass instance.

    You should read up on class constructors and pointers, if you're having trouble with this

    https://www.tutorialspoint.com/cplusplus/cpp_constructor_destructor.htm
    https://www.tutorialspoint.com/cplusplus/cpp_pointer_to_class.htm

    So I think I understood the problem exactly.

    When I did the things that you pointed, I have been creating two different first class so they can not communicate....

    Am I right?


  • Moderators

    @bladekel said in How to update qml text from two different cpp ?:

    Am I right?

    exactly, in the code you posted, firstClass exists 2 times. And those two instances do not now each other or interact with each other. They exist separately, like identical twins, operated at birth. One Lives with the mother, one with the father....



  • @J-Hilk said in How to update qml text from two different cpp ?:

    exactly, in the code you posted, firstClass exists 2 times. And those two instances do not now each other or interact with each other. They exist separately, like identical twins, operated at birth. One Lives with the mother, one with the father....

    So what I have to do is I think, creating the instance with same adress.


  • Lifetime Qt Champion

    @bladekel said in How to update qml text from two different cpp ?:

    creating the instance with same adress

    No, simply pass the pointer to firstClass instance as additional parameter to secondClass constructor as already was suggested.

    explicit secondClass(firstClass *frmFirstClass, QObject *parent = nullptr);
    

Log in to reply