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

How to update qml control periodically from c++ code



  • I want to update qml slider every second from c++ code how would I do it ?

    main.qml:

     Slider {               
                  id: new_slider
                  from: 0
                  to: 100
                  live: true               
                  value: "0"
                  stepSize: 1.0
             }
    

    Example.h:

    QTimer *timer;
    

    Example.cpp:

    Example::Example(QObject *parent) : QObject(parent)
    {
        timer = new QTimer(this);
        connect(timer, SIGNAL(timeout()),this,SLOT(update_slider()));
        timer->start(1000);
    }
    Example::~Example(){
        timer->stop();
    }
    void Example::update_slider(){
        // code for updating qml slider
    }
    

    how would I update the slider every second in c++ ? please help



  • @Ahti hi
    here are ways to Expose Attributes of C++ Types to QML you can use the first approach

    class Example: public QObject
    {
        Q_OBJECT
     // create a  qproperty to expose it to qml
        Q_PROPERTY(int val READ val WRITE setVal NOTIFY valChanged)
    public:
    
        void update_slider(){ // update
         setVal(m_val+1);
        }
    
        void setVal(const int &v) { 
            if (v != m_val) {
                m_val = v;
                emit valChanged();
            }
        }
        int val() const {
            return m_val;
        }
    
    signals:
        void valChanged(int);
    private:
        QTimer *timer;
        int m_val;
    };
    
    //expose class object to qml
    
    int main(int argc, char *argv[]) {
        QGuiApplication app(argc, argv);
    ...
        Example ex;
        view.engine()->rootContext()->setContextProperty("mycppObj", &ex);
      ..
    
        return app.exec();
    }
    // use the obect in qml 
     Slider {               
                  id: new_slider
                  from: 0
                  to: 100
                  live: true               
                  value: mycppObj.val //this will update
                  stepSize: 1.0
             }
    


  • @LeLev That doesn't update the slider after timeout



  • @Ahti ok , what we do now ? could you provide more info instead of asking other people to answer ?



  • ..tested example

    #ifndef EXAMPLE_H
    #define EXAMPLE_H
    
    #include <QObject>
    #include <QTimer>
    #include <QDebug>
    
    class Example : public QObject
    {
        Q_OBJECT
        Q_PROPERTY(int val READ val WRITE setVal NOTIFY valChanged)
    public:
        explicit Example(QObject *parent = nullptr);
        void setVal(const int &v) {
            if (v != m_val) {
                m_val = v;
                emit valChanged(v);
            }
        }
        int val() const {
            return m_val;
        }
    public slots:
        void update_slider(){ // update
            qDebug()<< "adding 1";
         setVal(m_val+1);
          qDebug()<< m_val;
        }
    signals:
        void valChanged(int);
    private:
        QTimer *timer;
        int m_val=0;
    };
    #endif // EXAMPLE_H
    #include "example.h"
    //.cpp
    Example::Example(QObject *parent) : QObject(parent)
    {
        timer = new QTimer(this);
            // old connect(timer, SIGNAL(timeout()),this,SLOT(update_slider()));
            QObject::connect(timer,&QTimer::timeout,this,&Example::update_slider);
            timer->start(1000);
    }
    //main
    #include <QGuiApplication>
    #include <QQmlApplicationEngine>
    #include <QDebug>
    #include <QQmlContext>
    #include <example.h>
    int main(int argc, char *argv[])
    {
        QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
        QGuiApplication app(argc, argv);
    
        Example e;
    
        QQmlApplicationEngine engine;
    
        engine.rootContext()->setContextProperty("ex",&e);
    
        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();
    }
    //qml
    import QtQuick 2.12
    import QtQuick.Window 2.12
    import QtQuick.Controls 2.12
    import QtQuick.Layouts 1.12
    
    Window {
        visible: true
        width: 640
        height: 480
        title: qsTr("Hello World")
    
        Slider{
            id:sl
            anchors.centerIn: parent
            from: 0
            to : 500
    
            value: ex.val
        }
    
    }
    
    


  • Okay thanks it works now :) And I have changed time to 500 milliseconds. But doesn't timer makes qt projects slower ? Isn't there any other better way ? like binding to an event which I think would reduce computation power because you don't have to periodically repeat the computation.


Log in to reply