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 Offline
    J Offline
    JJLim
    wrote on 9 Sept 2021, 03:38 last edited by
    #1

    Hi, may I know how to use thread to update value dynamically in C++? I am using processEvents() to update the infinity loop value, but I found that it is super lag. That's why I am wondering can we prevent this problem by using thread or not? If yes, I would like to seek for your guidelines. Thank you

    E 1 Reply Last reply 9 Sept 2021, 03:39
    0
    • J JJLim
      9 Sept 2021, 03:38

      Hi, may I know how to use thread to update value dynamically in C++? I am using processEvents() to update the infinity loop value, but I found that it is super lag. That's why I am wondering can we prevent this problem by using thread or not? If yes, I would like to seek for your guidelines. Thank you

      E Offline
      E Offline
      eyllanesc
      wrote on 9 Sept 2021, 03:39 last edited by
      #2

      @JJLim please provide a minimal and compilable example

      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 9 Sept 2021, 06:02 last edited by
        #3

        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;
        

        }

        E 1 Reply Last reply 9 Sept 2021, 06:32
        0
        • J JJLim
          9 Sept 2021, 06:02

          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;
          

          }

          E Offline
          E Offline
          eyllanesc
          wrote on 9 Sept 2021, 06:32 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 9 Sept 2021, 06:47 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 9 Sept 2021, 07:06
            0
            • J JJLim
              9 Sept 2021, 06:47

              @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 Offline
              J.HilkJ Offline
              J.Hilk
              Moderators
              wrote on 9 Sept 2021, 07:06 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 9 Sept 2021, 07:20 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 9 Sept 2021, 07:31 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 9 Sept 2021, 07:36
                  0
                  • J JJLim
                    9 Sept 2021, 07:31

                    @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 Offline
                    J.HilkJ Offline
                    J.Hilk
                    Moderators
                    wrote on 9 Sept 2021, 07:36 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 9 Sept 2021, 08:57 last edited by
                      #10

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

                      J.HilkJ 1 Reply Last reply 9 Sept 2021, 09:00
                      0
                      • J JJLim
                        9 Sept 2021, 08:57

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

                        J.HilkJ Offline
                        J.HilkJ Offline
                        J.Hilk
                        Moderators
                        wrote on 9 Sept 2021, 09:00 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 9 Sept 2021, 10:09 last edited by JJLim 9 Sept 2021, 10:10
                          #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 9 Sept 2021, 10:42
                          0
                          • J JJLim
                            9 Sept 2021, 10:09

                            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 Offline
                            J.HilkJ Offline
                            J.Hilk
                            Moderators
                            wrote on 9 Sept 2021, 10:42 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 9 Sept 2021, 11:23 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 31 Jan 2022, 11:42 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