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

QML update when c++ object value changed using Q_PROPERTY and NOTIFY



  • Hi,

    I have read a lot about this before posting here, sadly it seems it mostly uses a complete different approach.

    I have a digital clock in C++ (kicked a lot out to keep it simple, so only seconds here):

    digiclock.h :

    #ifndef DIGICLOCK_H
    #define DIGICLOCK_H
    
    #include <QObject>
    
    class digiclock : public QObject
    {
        Q_OBJECT   
        Q_PROPERTY (QString actualTimeSec READ actuTimeSec WRITE setActuTimeSec NOTIFY timeWasSetSec)
    
    public:
        explicit digiclock(QWidget *parent = nullptr);
    
        QString actuTimeSec();
    
    private:
        void setActuTimeSec(QString);
    
        QString m_actualTimeSec;
    
    private slots:
    
    signals:
        void timeWasSetSec(QString);
    };
    
    #endif
    

    and the digiclock.cpp:

    #include "digiclock.h"
    
    #include <QTime>
    #include <QTimer>
    
    digiclock::digiclock(QWidget *parent)
    {
    
        QTimer *timer = new QTimer(this);
        connect(timer, &QTimer::timeout, this, &digiclock::getTime);
        timer->start(1000);
        getTime();
    }
    
    void digiclock::getTime() {
        QTime time = QTime::currentTime();
        setActuTimeSec(time.toString("ss"));
    }
    
    QString digiclock::actuTimeSec()
    {
        return m_actualTimeSec;
    }
    
    void digiclock::setActuTimeSec(QString timeSec)
    {
        m_actualTimeSec = timeSec;    
        emit timeWasSetSec(timeSec);}
    

    every second, the new time is set to m_actualTimeSec. This update I need within my QML file.

    my main.cpp:

    #include <QGuiApplication>
    #include <QQmlApplicationEngine>
    
    #include "digiclock.h"
    
    int main(int argc, char *argv[])
    {    QCoreApplication::setAttribute(Qt::AA_DisableHighDpiScaling);
    
        QGuiApplication app(argc, argv);
    
        QQmlApplicationEngine engine;
        
        qmlRegisterType<digiclock>("DigitalClock", 1, 0, "Clock");
    
        engine.load(QUrl(QStringLiteral("qrc:/main.qml")));
        if (engine.rootObjects().isEmpty())
            return -1;
    
        return app.exec();
    }
    

    and the main.qml:

    import QtQuick 2.9
    import QtQuick.Controls 2.4
    import QtQuick.Layouts 1.3
    import QtQuick.Controls.Material 2.3
    
    import DigitalClock 1.0
    
    ApplicationWindow {
        id:root
        visible: true
        width: 800
        height: 480
        color: "#babdb6"
        title: qsTr("Welcome")
        //visibility: "FullScreen"
    
        Clock{
            id: myClock
        }
    
            Text {
                id: timeSec
                x: 305
                y: 51
                text: qsTr(myClock.actualTimeSec)
                font.pixelSize: 12
            }
        }    
    }
    

    I now have the ID myClock, which is an object of C++ - digiclock, created on load of the QML. I can perfectly set the actual time. Problem is, I dunno how to connect to the signal-slot of my digiclock-object from the QML files, so the seconds are updated every second.
    I have played around with signal - word and tried to implement it within the text field, with no success. What I need somewhere is the incoming signal to update timeSec.text, preferred within the QML directly and not also adding the signal within the main.cpp as shown on other examples.



  • dunno why it bugged, now it works.


Log in to reply