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. Slot on main thread not called when signal is emitted from another thread
QtWS25 Last Chance

Slot on main thread not called when signal is emitted from another thread

Scheduled Pinned Locked Moved Solved General and Desktop
14 Posts 5 Posters 8.5k 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 jsulm
    15 Dec 2015, 07:48

    You block the event loop of your thread, maybe this is the problem:

    void MyThread::run()
    {
    while (true)
    {
        qDebug() << "Running";
        sleep(3); // Here you block
        qDebug() << "Still Running";
        emit syncroGoFrame(22);
    }
    }
    
    P Offline
    P Offline
    PaulOfford
    wrote on 15 Dec 2015, 09:46 last edited by
    #3

    @jsulm Hi, I may have confused everyone here. I intended to block the thread with the sleep as this is just a test routine and I didn't want it to spin in a tight loop. The problem is that when the emit syncroGoFrame(22); is called I never get a call to Syncro::jumpToFrame(int new_frame).

    1 Reply Last reply
    0
    • M Offline
      M Offline
      mbruel
      wrote on 15 Dec 2015, 11:53 last edited by
      #4

      Did you start the event loop in the main thread?
      It should end up with an exec() and not be stuck in a loop without having reached it.
      Something like this:

      int main(int argc, char *argv[])
      {
          QCoreApplication a(argc, argv);
           .
           .
          .
      
          return a.exec(); // Run the event loop of main thread
      }
      

      In your example you just have a return, not return a.exec()

      1 Reply Last reply
      0
      • D Offline
        D Offline
        dheerendra
        Qt Champions 2022
        wrote on 15 Dec 2015, 11:54 last edited by
        #5

        You are doing the signal and slot across thread. Signal is sent from MyThread and Slot is main thread. Is there even main event loop started before you start your service thread ? I suspect that you may not be starting the event loop where the mainObject exist. Hence you are hitting the issue.

        Dheerendra
        @Community Service
        Certified Qt Specialist
        http://www.pthinks.com

        P 1 Reply Last reply 15 Dec 2015, 15:39
        5
        • D dheerendra
          15 Dec 2015, 11:54

          You are doing the signal and slot across thread. Signal is sent from MyThread and Slot is main thread. Is there even main event loop started before you start your service thread ? I suspect that you may not be starting the event loop where the mainObject exist. Hence you are hitting the issue.

          P Offline
          P Offline
          PaulOfford
          wrote on 15 Dec 2015, 15:39 last edited by
          #6

          @dheerendra and @mbruel thanks for your help. Wireshark is a QtWidget application and so as you would expect there is an event loop. The main function contains the line:

          /* Create The Wireshark app */
          WiresharkApplication ws_app(argc, argv);
          

          WiresharkApplication is defined like this:

          class WiresharkApplication : public QApplication
          {
              Q_OBJECT
              public:
                  explicit WiresharkApplication(int &argc,  char **argv);
          
              enum AppSignal {
                  ColumnsChanged,
                  FilterExpressionsChanged,
                  PacketDissectionChanged,
                  PreferencesChanged,
                  RecentFilesRead,
                  FieldsChanged
              };
          
              void registerUpdate(register_action_e action, const char *message);
              void emitAppSignal(AppSignal signal);
              .
              .
              const QString windowTitleString(QString title_part) { return windowTitleString(QStringList() << title_part); }
          
              QTranslator translator;
              QTranslator translatorQt;
              void loadLanguage(const QString& language);
          
          private:
              bool initialized_;
              bool is_reloading_lua_;
              QFont mono_font_;
              QTimer recent_timer_;
              .
              .
              int active_captures_;
          
          protected:
              bool event(QEvent *event);
          
          signals:
              void appInitialized();
              void localInterfaceListChanged();
          .
          .
          public slots:
              void clearRecentItems();
              void captureFileReadStarted();
              void captureStarted() { active_captures_++; }
              void captureFinished() { active_captures_--; }
              void updateTaps();
          
          private slots:
              void cleanup();
              void ifChangeEventsAvailable();
              void itemStatusFinished(const QString filename = "", qint64 size = 0, bool accessible = false);
              void refreshRecentFiles(void);
              void refreshAddressResolution(void);
          };
          
          extern WiresharkApplication *wsApp;
          

          The last line in the main function reads:

          return wsApp->exec();
          
          1 Reply Last reply
          0
          • B Offline
            B Offline
            bsomervi
            wrote on 15 Dec 2015, 18:33 last edited by
            #7

            If you want to pass signals between threads then you need an event loop in both the receiving thread and the sending thread. The default implementation of QThread::run() does this for you so if you do not override QThread::run() your signal will be passed. If you do override QThread::run() then you should finish with QThread::run() or simply call exec(). I doubt you need you override QThread::run() since it seems you are implementing a TCP/IP server using QTcpServer and this will play nicely with the thread event loop. Just make sure that you have the QTcpServer running in your thread and not the main GUI thread

            1 Reply Last reply
            0
            • D Offline
              D Offline
              dheerendra
              Qt Champions 2022
              wrote on 16 Dec 2015, 02:11 last edited by
              #8

              I still suspect the event loop issue at main thread. Your post says that Qt::DirectConnection works. But not Queued Connection. So implies that main thread is missing the event loop. It is possible that your thread is blocked for something else before starting the event loops ? I have sample prepared which exactly your scenario. I can you send you the same.

              Dheerendra
              @Community Service
              Certified Qt Specialist
              http://www.pthinks.com

              P 1 Reply Last reply 16 Dec 2015, 10:22
              4
              • D dheerendra
                16 Dec 2015, 02:11

                I still suspect the event loop issue at main thread. Your post says that Qt::DirectConnection works. But not Queued Connection. So implies that main thread is missing the event loop. It is possible that your thread is blocked for something else before starting the event loops ? I have sample prepared which exactly your scenario. I can you send you the same.

                P Offline
                P Offline
                PaulOfford
                wrote on 16 Dec 2015, 10:22 last edited by
                #9

                @bsomervi I tried adding the exec() to the end of QThread::run() but that made no difference. I'm not surprised since the while (TRUE) loop means it never executes the exec(). Also, I used the Qt Mandelbrot example ( http://doc.qt.io/qt-4.8/qt-threads-mandelbrot-example.html ) as a guide and this overrides the run() function in much the same way as I have done it.

                @dheerendra I think you are right that it's a main thread event loop issue. Even though I have the problem Wireshark remains responsive to the user. If the main thread event loop was blocked wouldn't the application freeze?

                It might help if I understood how the slot gets included in the event loop. As the slot is connected via my plugin DLL I assume that there is some mechanism that inserts my slot into the main thread event loop at run time. How does this work?

                1 Reply Last reply
                0
                • D Offline
                  D Offline
                  dheerendra
                  Qt Champions 2022
                  wrote on 16 Dec 2015, 10:51 last edited by
                  #10

                  in the current scenario exec().. in worker thread will not help. Here worker thread is sending the signal. So event will not in worker thread will not help.

                  According to you, your Main UI works fine. If the main event loop is issue UI would have been freezed. This puts other question in my mind.

                  How many threads are there your program ? I think mainObject is not created in main thread. It would have been created by another worker thread. That thread may not have even loop.

                  Just to ensure that can you print QThread::currentThreadID() in main and also in initialise method ?

                  Also you don't have to do anything for inserting the slot in to main thread event loop. It internally create the QEvent subclass object and post this to destination thread event loop.

                  Dheerendra
                  @Community Service
                  Certified Qt Specialist
                  http://www.pthinks.com

                  P 1 Reply Last reply 16 Dec 2015, 14:01
                  4
                  • D dheerendra
                    16 Dec 2015, 10:51

                    in the current scenario exec().. in worker thread will not help. Here worker thread is sending the signal. So event will not in worker thread will not help.

                    According to you, your Main UI works fine. If the main event loop is issue UI would have been freezed. This puts other question in my mind.

                    How many threads are there your program ? I think mainObject is not created in main thread. It would have been created by another worker thread. That thread may not have even loop.

                    Just to ensure that can you print QThread::currentThreadID() in main and also in initialise method ?

                    Also you don't have to do anything for inserting the slot in to main thread event loop. It internally create the QEvent subclass object and post this to destination thread event loop.

                    P Offline
                    P Offline
                    PaulOfford
                    wrote on 16 Dec 2015, 14:01 last edited by
                    #11

                    @dheerendra I used g_thread_self() rather than QThread::currentThreadID() as it was much easier in the main function. The details are:

                    • GThread pointer in main - 0x02181000
                    • GThread pointer in Syncro::Initialise - 0x02181000
                    • GThread pointer in MyThread::run() - 0x6bf54e0

                    Best regards...Paul

                    1 Reply Last reply
                    0
                    • D Offline
                      D Offline
                      dheerendra
                      Qt Champions 2022
                      wrote on 16 Dec 2015, 14:31 last edited by
                      #12

                      It is interesting now. Is it related to your other problem where qApp is become NULL ? By any chance your UI Widgets are created in different thread rather than the main thread ?

                      Dheerendra
                      @Community Service
                      Certified Qt Specialist
                      http://www.pthinks.com

                      1 Reply Last reply
                      3
                      • P Offline
                        P Offline
                        PaulOfford
                        wrote on 16 Dec 2015, 14:38 last edited by
                        #13

                        Well that was one long side track. The answer to my problem is that I had indeed mixed release and debug objects. I have been adding Qt Libraries to the Linker Input list like this:

                        \Qt\Qt5.5.1\5.5\msvc2013_64\lib\Qt5Core.lib
                        \Qt\Qt5.5.1\5.5\msvc2013_64\lib\Qt5Widgets.lib
                        \Qt\Qt5.5.1\5.5\msvc2013_64\lib\Qt5Gui.lib
                        \Qt\Qt5.5.1\5.5\msvc2013_64\lib\Qt5Network.lib

                        I have now changed the include list to:

                        \Qt\Qt5.5.1\5.5\msvc2013_64\lib\Qt5Cored.lib
                        \Qt\Qt5.5.1\5.5\msvc2013_64\lib\Qt5Widgetsd.lib
                        \Qt\Qt5.5.1\5.5\msvc2013_64\lib\Qt5Guid.lib
                        \Qt\Qt5.5.1\5.5\msvc2013_64\lib\Qt5Networkd.lib

                        and voila - all is working.

                        Thanks to everyone who has been advising me here.

                        1 Reply Last reply
                        0
                        • D Offline
                          D Offline
                          dheerendra
                          Qt Champions 2022
                          wrote on 17 Dec 2015, 02:12 last edited by
                          #14

                          cool man. I answer has indeed helped(mix of debug/release from other qn) you can make this qn solved, upvote. Have good time.

                          Dheerendra
                          @Community Service
                          Certified Qt Specialist
                          http://www.pthinks.com

                          1 Reply Last reply
                          3

                          12/14

                          16 Dec 2015, 14:31

                          • Login

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