Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. Update qml value dynamically in C++ using thread
Forum Updated to NodeBB v4.3 + New Features

Update qml value dynamically in C++ using thread

Scheduled Pinned Locked Moved Solved General and Desktop
15 Posts 4 Posters 2.2k Views
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • J JJLim

    Code below is the example that I refer to https://doc.qt.io/archives/3.3/qthread.html . However, step2b is not executed successfully, so how can I upload qml value via QThread?

    #include <QGuiApplication>
    #include <QQmlApplicationEngine>
    #include <QThread>
    #include <QDebug>

    int value;

    class MyThread : public QThread {

    public:
    virtual void run();
    };

    void MyThread::run()
    {
    int count = 0;
    for( ;; ) {
    sleep( 2 );
    value = count;
    count++;
    }
    }

    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;
    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);
    
    // Step 1: get access to the root object
    QObject *rootObject = engine.rootObjects().first();
    QObject *qmlObject = rootObject->findChild<QObject*>("progressbar");
    
    MyThread a;
    MyThread b;
    a.start();
    b.start();
    // Step 2b: set or get the desired property value for any qml object
    // qmlObject->setProperty("value", value);
    // qDebug() << qmlObject->property("visible");
    app.exec();
    a.wait();
    b.wait();
    
    return 0;
    

    }

    eyllanescE Offline
    eyllanescE Offline
    eyllanesc
    wrote on last edited by
    #4

    @JJLim Demo:

    #include <QGuiApplication>
    #include <QQmlApplicationEngine>
    #include <QQmlContext>
    #include <QtConcurrent>
    
    
    class Helper: public QObject{
        Q_OBJECT
    public:
        using QObject::QObject;
        Q_INVOKABLE void start(){
            doWork();
        }
    signals:
        void progressChanged(int);
    private:
        void doWork(){
            QtConcurrent::run([=]{
                for(int i=0; i < 100; i++){
                    emit progressChanged(i);
                    QThread::sleep(1);
                }
            });
        }
    };
    
    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);
        Helper helper;
    
        QQmlApplicationEngine engine;
        engine.rootContext()->setContextProperty("helper", &helper);
        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();
    }
    
    #include "main.moc"
    
    import QtQuick 2.15
    import QtQuick.Window 2.15
    import QtQuick.Controls 2.15
    
    Window {
        width: 640
        height: 480
        visible: true
        title: qsTr("Hello World")
        ProgressBar {
            id: progressbar
            from: 0
            to: 100
            anchors.centerIn: parent
            width: 300
        }
        Connections{
            target: helper
            function onProgressChanged(i){
                progressbar.value = i
            }
        }
        Component.onCompleted: helper.start()
    }
    

    If you want me to help you develop some work then you can write to my email: e.yllanescucho@gmal.com.

    1 Reply Last reply
    0
    • J Offline
      J Offline
      JJLim
      wrote on last edited by
      #5

      @eyllanesc Thank you very much, it works perfectly!!!

      Btw may I know how the QThread works, if I have 4 threads, so the tasks will be separated evenly among these 4 threads? Can I assume that it works like the POSIX threads?

      J.HilkJ 1 Reply Last reply
      0
      • J JJLim

        @eyllanesc Thank you very much, it works perfectly!!!

        Btw may I know how the QThread works, if I have 4 threads, so the tasks will be separated evenly among these 4 threads? Can I assume that it works like the POSIX threads?

        J.HilkJ Online
        J.HilkJ Online
        J.Hilk
        Moderators
        wrote on last edited by
        #6

        @JJLim out of curiosity,
        what makes you think you need threads in the first place? (all)most Qt classes are asynchronous in nature. And needing to use sleep is usually a sign for immature design/implementation, or admittedly very low level operations (polling level changes on input pins for example)


        Be aware of the Qt Code of Conduct, when posting : https://forum.qt.io/topic/113070/qt-code-of-conduct


        Q: What's that?
        A: It's blue light.
        Q: What does it do?
        A: It turns blue.

        1 Reply Last reply
        0
        • J Offline
          J Offline
          JJLim
          wrote on last edited by
          #7

          I see, thks for your explanation.

          @J-Hilk I was thinking to use thread for preventing some laggy issues. For exp, the qml components (progress bar) are updated based on the infinity loop in the C++, this process makes the display almost freeze. That's why I am thinking is it possible to use thread to overcome this issue or not.

          I am still learning about it, so I would like to explore something news haha.

          Btw, thank you very much for your guidance @eyllanesc , it helps me a lot.

          1 Reply Last reply
          0
          • J Offline
            J Offline
            JJLim
            wrote on last edited by
            #8

            @J-Hilk So based on your explanation, is it possible that thread can be used to solve the GUI laggy issue when updating the value during the runtime (infinity loops). Or is there any alternative method to prevent this kind of issue?

            The code has been attached, when I add more infinity loops, my qt GUI will almost freeze, not sure is it due to the coding problem or it is actually the PC issues haha.

            J.HilkJ 1 Reply Last reply
            0
            • J JJLim

              @J-Hilk So based on your explanation, is it possible that thread can be used to solve the GUI laggy issue when updating the value during the runtime (infinity loops). Or is there any alternative method to prevent this kind of issue?

              The code has been attached, when I add more infinity loops, my qt GUI will almost freeze, not sure is it due to the coding problem or it is actually the PC issues haha.

              J.HilkJ Online
              J.HilkJ Online
              J.Hilk
              Moderators
              wrote on last edited by
              #9

              @JJLim said in Update qml value dynamically in C++ using thread:

              based on the infinity loop in the C++

              rights thats my point, what are you doing in those infinite loops?


              Be aware of the Qt Code of Conduct, when posting : https://forum.qt.io/topic/113070/qt-code-of-conduct


              Q: What's that?
              A: It's blue light.
              Q: What does it do?
              A: It turns blue.

              1 Reply Last reply
              0
              • J Offline
                J Offline
                JJLim
                wrote on last edited by
                #10

                Fyi, the purpose of infinity loop is for keep updating the value.

                J.HilkJ 1 Reply Last reply
                0
                • J JJLim

                  Fyi, the purpose of infinity loop is for keep updating the value.

                  J.HilkJ Online
                  J.HilkJ Online
                  J.Hilk
                  Moderators
                  wrote on last edited by
                  #11

                  @JJLim said in Update qml value dynamically in C++ using thread:

                  Fyi, the purpose of infinity loop is for keep updating the value.

                  yes of course but why are you using an infinite loop instead of a QTimer, you can't update the UI faster than every 20(ish) ms anyway


                  Be aware of the Qt Code of Conduct, when posting : https://forum.qt.io/topic/113070/qt-code-of-conduct


                  Q: What's that?
                  A: It's blue light.
                  Q: What does it do?
                  A: It turns blue.

                  1 Reply Last reply
                  0
                  • J Offline
                    J Offline
                    JJLim
                    wrote on last edited by JJLim
                    #12

                    oic, so what u mean is I can just use QTimer to update qml component dynamically? Can I have a relevant example for the further clarification?

                    Bcuz what am I doing now is set an infinity loop, within the loop, I use std::this_thread::sleep_for() to let the GUI accept new value for n interval haha

                    Sorry for asking so many questions, I am newbie to Qt and learning now

                    J.HilkJ 1 Reply Last reply
                    0
                    • J JJLim

                      oic, so what u mean is I can just use QTimer to update qml component dynamically? Can I have a relevant example for the further clarification?

                      Bcuz what am I doing now is set an infinity loop, within the loop, I use std::this_thread::sleep_for() to let the GUI accept new value for n interval haha

                      Sorry for asking so many questions, I am newbie to Qt and learning now

                      J.HilkJ Online
                      J.HilkJ Online
                      J.Hilk
                      Moderators
                      wrote on last edited by
                      #13

                      @JJLim here, the modified Helper class from @eyllanesc example

                      class Helper: public QObject{
                          Q_OBJECT
                          
                      public:
                          explicit Helper(QObject *parent = nullptr): QObject(parent)
                          {
                              m_tUpdateProgress.setInterval(1000); // 1000ms -> every second
                              connect(&m_tUpdateProgress, &QTimer::timeout, this, &Helper::doWork);
                          }
                          
                      public slots:
                          void start(){
                              m_progress = 0;
                              m_tUpdateProgress.start();
                          }
                          void stop(){
                              m_tUpdateProgress.stop();
                          }
                      signals:
                          void progressChanged(int);
                      
                      private:
                          void doWork(){
                              m_progress++;
                              emit progressChanged(m_progress);
                          }
                          
                      private:
                          int32_t m_progress{0};
                          QTimer m_tUpdateProgress;
                      };
                      

                      Be aware of the Qt Code of Conduct, when posting : https://forum.qt.io/topic/113070/qt-code-of-conduct


                      Q: What's that?
                      A: It's blue light.
                      Q: What does it do?
                      A: It turns blue.

                      1 Reply Last reply
                      1
                      • J Offline
                        J Offline
                        JJLim
                        wrote on last edited by
                        #14

                        Wow it works perfectly!!!

                        Thank you very much for your guidance ^.^
                        I got it now haha

                        1 Reply Last reply
                        1
                        • P Offline
                          P Offline
                          Pradeep NS
                          wrote on last edited by
                          #15

                          It was a great help for running threads. Running in QtConcurrent::run([=], really solved all the issues of my UI non responsive ness.. Thanks a lot for your help

                          1 Reply Last reply
                          0

                          • Login

                          • Login or register to search.
                          • First post
                            Last post
                          0
                          • Categories
                          • Recent
                          • Tags
                          • Popular
                          • Users
                          • Groups
                          • Search
                          • Get Qt Extensions
                          • Unsolved