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 GUI from QThread
Forum Updated to NodeBB v4.3 + New Features

Update GUI from QThread

Scheduled Pinned Locked Moved Solved General and Desktop
5 Posts 3 Posters 5.0k Views 3 Watching
  • 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.
  • Andy314A Offline
    Andy314A Offline
    Andy314
    wrote on last edited by Andy314
    #1

    I want update (animate) a widget independent from the main thread.
    Here is my Thread:

    void MyThread::run()
    {
        while(true)
        {
            emit timerElapsed();
            msleep(100);
            k17++;
            qDebug()<<"run "<<k17;
        }
       //start();
       emit timerElapsed();
    }
    

    Here is my connection

    connect(&mythread, SIGNAL(timerElapsed()),
              ui->advCircularProgress, SLOT(nextStep()));
    mythread.start();
    

    This should work - but it does not.

    When I start a time consuming action in the main thread (Database-Table-refresh)
    the animation stops. It seems that it is not primary a repaint problem, but the
    emit timerElapsed() does not receive the widget nextStep(); when it is emitted
    It receives all pending signals in a queue later, when the main thread is ready.

    What do I wrong!

    kshegunovK JKSHJ 2 Replies Last reply
    0
    • Andy314A Andy314

      I want update (animate) a widget independent from the main thread.
      Here is my Thread:

      void MyThread::run()
      {
          while(true)
          {
              emit timerElapsed();
              msleep(100);
              k17++;
              qDebug()<<"run "<<k17;
          }
         //start();
         emit timerElapsed();
      }
      

      Here is my connection

      connect(&mythread, SIGNAL(timerElapsed()),
                ui->advCircularProgress, SLOT(nextStep()));
      mythread.start();
      

      This should work - but it does not.

      When I start a time consuming action in the main thread (Database-Table-refresh)
      the animation stops. It seems that it is not primary a repaint problem, but the
      emit timerElapsed() does not receive the widget nextStep(); when it is emitted
      It receives all pending signals in a queue later, when the main thread is ready.

      What do I wrong!

      kshegunovK Offline
      kshegunovK Offline
      kshegunov
      Moderators
      wrote on last edited by kshegunov
      #2

      @Andy314
      The painting and GUI happens all in the main thread, you can't change that. When you have multiple threads the receiver slot's object determines in which thread the slot will be invoked (see QObject's thread affinity documentation). So what you're doing is to schedule the updates in the main thread. This is why when the event loop of the main thread is busy you get the repaints done later.

      Read and abide by the Qt Code of Conduct

      Andy314A 1 Reply Last reply
      0
      • kshegunovK kshegunov

        @Andy314
        The painting and GUI happens all in the main thread, you can't change that. When you have multiple threads the receiver slot's object determines in which thread the slot will be invoked (see QObject's thread affinity documentation). So what you're doing is to schedule the updates in the main thread. This is why when the event loop of the main thread is busy you get the repaints done later.

        Andy314A Offline
        Andy314A Offline
        Andy314
        wrote on last edited by Andy314
        #3

        @kshegunov
        You say that it is not possible to make independent GUI-animation from the main thread !?
        I must write everywhere QCoreApplication::processEvents(); ?
        For my own code this is uncomfortable but possible - for other code in libs this is not possible.
        Taking the time consuming code in a other thread works for pure code but usually I make here other GUI stuff too.

        Is there really no solution for forcing a widget update from a other thread ?

        kshegunovK 1 Reply Last reply
        0
        • Andy314A Andy314

          @kshegunov
          You say that it is not possible to make independent GUI-animation from the main thread !?
          I must write everywhere QCoreApplication::processEvents(); ?
          For my own code this is uncomfortable but possible - for other code in libs this is not possible.
          Taking the time consuming code in a other thread works for pure code but usually I make here other GUI stuff too.

          Is there really no solution for forcing a widget update from a other thread ?

          kshegunovK Offline
          kshegunovK Offline
          kshegunov
          Moderators
          wrote on last edited by
          #4

          @Andy314

          must write everywhere QCoreApplication::processEvents(); ?

          This processes the events, nothing more, I'd suggest redesigning your code so you don't need to call that function at all (for example running your thread with an event loop and a timer, not subclassing QThread).

          Taking the time consuming code in a other thread works for pure code but usually I make here other GUI stuff too.

          You can prepare in a worker thread whatever is that needs to be done in the GUI and schedule the painting at the appropriate times (by signal-slots), the painting itself, however, will (and should) be happening in the main thread.

          Is there really no solution for forcing a widget update from a other thread ?

          You can only request a widget to be repainted from another thread, when the event that's posted gets processed the widget itself will be updated. If you want to directly repaint a widget from a thread different from the main, well, that's not possible. I don't know any toolkit to support threaded GUI in any case (OpenGL painting excluded).

          Read and abide by the Qt Code of Conduct

          1 Reply Last reply
          0
          • Andy314A Andy314

            I want update (animate) a widget independent from the main thread.
            Here is my Thread:

            void MyThread::run()
            {
                while(true)
                {
                    emit timerElapsed();
                    msleep(100);
                    k17++;
                    qDebug()<<"run "<<k17;
                }
               //start();
               emit timerElapsed();
            }
            

            Here is my connection

            connect(&mythread, SIGNAL(timerElapsed()),
                      ui->advCircularProgress, SLOT(nextStep()));
            mythread.start();
            

            This should work - but it does not.

            When I start a time consuming action in the main thread (Database-Table-refresh)
            the animation stops. It seems that it is not primary a repaint problem, but the
            emit timerElapsed() does not receive the widget nextStep(); when it is emitted
            It receives all pending signals in a queue later, when the main thread is ready.

            What do I wrong!

            JKSHJ Offline
            JKSHJ Offline
            JKSH
            Moderators
            wrote on last edited by
            #5

            @Andy314 said:

            When I start a time consuming action in the main thread (Database-Table-refresh)
            the animation stops. It seems that it is not primary a repaint problem, but the
            emit timerElapsed() does not receive the widget nextStep(); when it is emitted
            It receives all pending signals in a queue later, when the main thread is ready.

            The main thread cannot refresh the database and update the GUI at the same time.

            To make your GUI respond quickly, you have 3 options:

            1. Use a different thread to access your database, OR
            2. Optimize your database-access code so that it is not time-consuming, OR
            3. Make your database-access code call QCoreApplication::processEvents() to process signals. (Note: Option #3 is easiest, but it is not a robust design)

            Qt Doc Search for browsers: forum.qt.io/topic/35616/web-browser-extension-for-improved-doc-searches

            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