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. QThread with loop cannot have other slot called (while loop is running) ?
Qt 6.11 is out! See what's new in the release blog

QThread with loop cannot have other slot called (while loop is running) ?

Scheduled Pinned Locked Moved Solved General and Desktop
11 Posts 3 Posters 6.3k Views 1 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.
  • R Offline
    R Offline
    rXpSwiss
    wrote on last edited by rXpSwiss
    #1

    Hello,

    I have a simple question :
    I have a QThread with a compute function called when the thread is started :

    void MyThread::compute()
    {
        while(m_run)
        {
    
        //do things
        QThread::sleep(1000);
    }
    emit(finished());
    

    }

    Now that will run until I ask the thread to stop.
    Other than that I have another slot that should be called more than once while this is running :

    void MyThread::deleteThing(const QString& name)
    {
        qDebug() << QString("delete");
        QMutexLocker locker(&m_mutex);
        //things to delete
    }
    

    My issue is that this slot is never called while the main loop is running.
    What should I do differently ? I shouldn't use thread here ?

    rXp

    1 Reply Last reply
    0
    • mrjjM Offline
      mrjjM Offline
      mrjj
      Lifetime Qt Champion
      wrote on last edited by mrjj
      #2

      Hi
      Signals and slots need a event loop running. (exec())
      so if u also overrode run() and call compute it might be therefore. Default it does call exec()
      Maybe using a worker object will just work for you.

      https://mayaposch.wordpress.com/2011/11/01/how-to-really-truly-use-qthreads-the-full-explanation/

      also look here
      https://bugreports.qt.io/secure/attachment/64230/qsp-no-freeze-workaround-windows.zip
      for other sample.

      R 1 Reply Last reply
      1
      • mrjjM mrjj

        Hi
        Signals and slots need a event loop running. (exec())
        so if u also overrode run() and call compute it might be therefore. Default it does call exec()
        Maybe using a worker object will just work for you.

        https://mayaposch.wordpress.com/2011/11/01/how-to-really-truly-use-qthreads-the-full-explanation/

        also look here
        https://bugreports.qt.io/secure/attachment/64230/qsp-no-freeze-workaround-windows.zip
        for other sample.

        R Offline
        R Offline
        rXpSwiss
        wrote on last edited by rXpSwiss
        #3

        @mrjj I did it this way :

        mythread= new QThread;
            MyWorker* worker = new MyWorker();
            worker->moveToThread(mythread);
            connect(worker, SIGNAL(threadFinished(const QString&)), this, SLOT(updateStatus(const QString&)));
            connect(mythread, SIGNAL(started()), worker, SLOT(compute()));
            connect(worker, SIGNAL(finished()), mythread, SLOT(quit()));
            connect(worker, SIGNAL(finished()), worker, SLOT(deleteLater()));
            connect(mythread, SIGNAL(finished()), worker, SLOT(stop()));
            connect(this, SIGNAL(deleteThing(const QString&)), worker, SLOT(deleteThing(const QString&)));
            mythread->start();
        

        So my worker is put into a thread and the slot and signal a connected to my main UI class.

        mrjjM 1 Reply Last reply
        0
        • R rXpSwiss

          @mrjj I did it this way :

          mythread= new QThread;
              MyWorker* worker = new MyWorker();
              worker->moveToThread(mythread);
              connect(worker, SIGNAL(threadFinished(const QString&)), this, SLOT(updateStatus(const QString&)));
              connect(mythread, SIGNAL(started()), worker, SLOT(compute()));
              connect(worker, SIGNAL(finished()), mythread, SLOT(quit()));
              connect(worker, SIGNAL(finished()), worker, SLOT(deleteLater()));
              connect(mythread, SIGNAL(finished()), worker, SLOT(stop()));
              connect(this, SIGNAL(deleteThing(const QString&)), worker, SLOT(deleteThing(const QString&)));
              mythread->start();
          

          So my worker is put into a thread and the slot and signal a connected to my main UI class.

          mrjjM Offline
          mrjjM Offline
          mrjj
          Lifetime Qt Champion
          wrote on last edited by
          #4

          @rXpSwiss
          Super.
          So that works now?

          R 1 Reply Last reply
          1
          • mrjjM mrjj

            @rXpSwiss
            Super.
            So that works now?

            R Offline
            R Offline
            rXpSwiss
            wrote on last edited by
            #5

            @mrjj No, that was my solution from the beginning. :(

            mrjjM 1 Reply Last reply
            0
            • R rXpSwiss

              @mrjj No, that was my solution from the beginning. :(

              mrjjM Offline
              mrjjM Offline
              mrjj
              Lifetime Qt Champion
              wrote on last edited by
              #6

              @rXpSwiss
              ok but you show
              void MyThread::compute()

              seems like a thread sub class, but its not ?
              Its the worker ?

              R 1 Reply Last reply
              1
              • mrjjM mrjj

                @rXpSwiss
                ok but you show
                void MyThread::compute()

                seems like a thread sub class, but its not ?
                Its the worker ?

                R Offline
                R Offline
                rXpSwiss
                wrote on last edited by rXpSwiss
                #7

                @mrjj It is the worker.
                The idea is that when I do myThread->start() the thread will call compute() in my worker so the main loop is started.
                But while this loop runs, I can call no other signal in my worker.

                jsulmJ 1 Reply Last reply
                0
                • R rXpSwiss

                  @mrjj It is the worker.
                  The idea is that when I do myThread->start() the thread will call compute() in my worker so the main loop is started.
                  But while this loop runs, I can call no other signal in my worker.

                  jsulmJ Offline
                  jsulmJ Offline
                  jsulm
                  Lifetime Qt Champion
                  wrote on last edited by mrjj
                  #8

                  @rXpSwiss The compute() method is blocking the event loop, so as long as it runs no slots will be executed. You should at least call http://doc.qt.io/qt-5/qcoreapplication.html#processEvents in your loop, or redesign your thread to get rid of this blocking loop.

                  https://forum.qt.io/topic/113070/qt-code-of-conduct

                  R 1 Reply Last reply
                  3
                  • jsulmJ jsulm

                    @rXpSwiss The compute() method is blocking the event loop, so as long as it runs no slots will be executed. You should at least call http://doc.qt.io/qt-5/qcoreapplication.html#processEvents in your loop, or redesign your thread to get rid of this blocking loop.

                    R Offline
                    R Offline
                    rXpSwiss
                    wrote on last edited by
                    #9

                    @jsulm
                    So as I thought my way of doing it is the problem.
                    Now this is my basic problem :
                    I have a list of things I need to check on every X seconds.
                    If a change is detected I will tell the main thread to update the UI.
                    If not keep checking.
                    On the other side you can add new things (that have their own thread (but not QT)) and I need to tell my worker that a new thing is here.

                    So I should processEvents here ? Or how would you handle that ?

                    jsulmJ 1 Reply Last reply
                    0
                    • R rXpSwiss

                      @jsulm
                      So as I thought my way of doing it is the problem.
                      Now this is my basic problem :
                      I have a list of things I need to check on every X seconds.
                      If a change is detected I will tell the main thread to update the UI.
                      If not keep checking.
                      On the other side you can add new things (that have their own thread (but not QT)) and I need to tell my worker that a new thing is here.

                      So I should processEvents here ? Or how would you handle that ?

                      jsulmJ Offline
                      jsulmJ Offline
                      jsulm
                      Lifetime Qt Champion
                      wrote on last edited by
                      #10

                      @rXpSwiss You should use QTimer set to 1 second timeout, connect a slot to it and in this slot check for changes. No need to have an endless loop for that. If this checking does not take long you can even do it in your GUI thread (so no need for a second thread).

                      https://forum.qt.io/topic/113070/qt-code-of-conduct

                      R 1 Reply Last reply
                      3
                      • jsulmJ jsulm

                        @rXpSwiss You should use QTimer set to 1 second timeout, connect a slot to it and in this slot check for changes. No need to have an endless loop for that. If this checking does not take long you can even do it in your GUI thread (so no need for a second thread).

                        R Offline
                        R Offline
                        rXpSwiss
                        wrote on last edited by rXpSwiss
                        #11

                        @jsulm
                        Since the number of elements has no real limit in the code, I worry it still might block the GUI a bit.
                        But I could use QTimer in the thread.

                        Edit : Thank you it works fine, I am still not used to all QT tools :)

                        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