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

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 9.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.
  • dheerendraD Offline
    dheerendraD Offline
    dheerendra
    Qt Champions 2022
    wrote on 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
    5
    • dheerendraD dheerendra

      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 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 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
        • dheerendraD Offline
          dheerendraD Offline
          dheerendra
          Qt Champions 2022
          wrote on 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
          4
          • dheerendraD dheerendra

            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 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
            • dheerendraD Offline
              dheerendraD Offline
              dheerendra
              Qt Champions 2022
              wrote on 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
              4
              • dheerendraD dheerendra

                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 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
                • dheerendraD Offline
                  dheerendraD Offline
                  dheerendra
                  Qt Champions 2022
                  wrote on 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 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
                    • dheerendraD Offline
                      dheerendraD Offline
                      dheerendra
                      Qt Champions 2022
                      wrote on 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

                      • Login

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