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. Invoking a slot from a non-Qt thread
Forum Updated to NodeBB v4.3 + New Features

Invoking a slot from a non-Qt thread

Scheduled Pinned Locked Moved Unsolved General and Desktop
12 Posts 6 Posters 295 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.
  • P Offline
    P Offline
    Perdrix
    wrote 29 days ago last edited by
    #1

    I correct to think that there's only two ways to invoke a slot from a non-QObject based thread?

    • Use QMetaObject::invokeMethod(), or

    • emit a signal (can I do that on a non Qt thread?)

    Thanks
    David

    J 1 Reply Last reply 29 days ago
    0
    • C Offline
      C Offline
      Christian Ehrlicher
      Lifetime Qt Champion
      wrote 29 days ago last edited by
      #2

      Emit a signal.

      Qt Online Installer direct download: https://download.qt.io/official_releases/online_installers/
      Visit the Qt Academy at https://academy.qt.io/catalog

      1 Reply Last reply
      0
      • P Perdrix
        29 days ago

        I correct to think that there's only two ways to invoke a slot from a non-QObject based thread?

        • Use QMetaObject::invokeMethod(), or

        • emit a signal (can I do that on a non Qt thread?)

        Thanks
        David

        J Offline
        J Offline
        JonB
        wrote 29 days ago last edited by
        #3

        @Perdrix
        @Christian-Ehrlicher will correct me if I am wrong. Yes, you can emit a signal from a non-QObject based thread. But you still need a "context object" to emit the signal and pass to the connect(). And that needs to be a QObject. And you will use a queued connection. I guess QMetaObject::invokeMethod() will skip the need to have an emitting QObject.

        You will also a need a receiving QObject, for both cases. The Qt event loop needs to be running in the receiver thread to dispatch the slots.

        Am I right, Christian?

        References:
        https://stackoverflow.com/questions/41044526/qt-5-emit-signal-from-non-qt-thread
        https://stackoverflow.com/questions/24982324/qt-emit-a-signal-from-a-c-thread
        https://www.qtcentre.org/threads/65029-Emitting-signal-from-a-non-Qt-Thread

        C 1 Reply Last reply 29 days ago
        0
        • J JonB
          29 days ago

          @Perdrix
          @Christian-Ehrlicher will correct me if I am wrong. Yes, you can emit a signal from a non-QObject based thread. But you still need a "context object" to emit the signal and pass to the connect(). And that needs to be a QObject. And you will use a queued connection. I guess QMetaObject::invokeMethod() will skip the need to have an emitting QObject.

          You will also a need a receiving QObject, for both cases. The Qt event loop needs to be running in the receiver thread to dispatch the slots.

          Am I right, Christian?

          References:
          https://stackoverflow.com/questions/41044526/qt-5-emit-signal-from-non-qt-thread
          https://stackoverflow.com/questions/24982324/qt-emit-a-signal-from-a-c-thread
          https://www.qtcentre.org/threads/65029-Emitting-signal-from-a-non-Qt-Thread

          C Offline
          C Offline
          Christian Ehrlicher
          Lifetime Qt Champion
          wrote 29 days ago last edited by
          #4

          @JonB said in Invoking a slot from a non-Qt thread:

          Am I right, Christian?

          Yes, but the question was if it can be invoked from a std::thread (or other non QThread based one). Nothing about what object it is 🙂

          Qt Online Installer direct download: https://download.qt.io/official_releases/online_installers/
          Visit the Qt Academy at https://academy.qt.io/catalog

          J 1 Reply Last reply 29 days ago
          0
          • C Christian Ehrlicher
            29 days ago

            @JonB said in Invoking a slot from a non-Qt thread:

            Am I right, Christian?

            Yes, but the question was if it can be invoked from a std::thread (or other non QThread based one). Nothing about what object it is 🙂

            J Offline
            J Offline
            JonB
            wrote 29 days ago last edited by JonB 5 Mar 2025, 12:04
            #5

            @Christian-Ehrlicher said in Invoking a slot from a non-Qt thread:

            Yes, but the question was if it can be invoked from a std::thread (or other non QThread based one). Nothing about what object it is 🙂

            Oh indeed! And the reference links are about that, e.g. the second one is about

            I want to emit a signal from a C++ thread (std::thread) in Qt.

            I just meant that OP is going to need to Qt objects around from somewhere in the thread. I agree with you that emit signal is the obvious route. But, just for the record, a non-Qt thread can use QMetaObject::invokeMethod() to call a slot if it has access to a receiving object but not a sending one to do a connect(). Right?

            C 1 Reply Last reply 29 days ago
            0
            • J JonB
              29 days ago

              @Christian-Ehrlicher said in Invoking a slot from a non-Qt thread:

              Yes, but the question was if it can be invoked from a std::thread (or other non QThread based one). Nothing about what object it is 🙂

              Oh indeed! And the reference links are about that, e.g. the second one is about

              I want to emit a signal from a C++ thread (std::thread) in Qt.

              I just meant that OP is going to need to Qt objects around from somewhere in the thread. I agree with you that emit signal is the obvious route. But, just for the record, a non-Qt thread can use QMetaObject::invokeMethod() to call a slot if it has access to a receiving object but not a sending one to do a connect(). Right?

              C Offline
              C Offline
              Christian Ehrlicher
              Lifetime Qt Champion
              wrote 29 days ago last edited by
              #6

              @JonB said in Invoking a slot from a non-Qt thread:

              a non-Qt thread can use QMetaObject::invokeMethod() to call a slot if it has access to a receiving object but not a sending one to do a connect(). Right?

              Yes. But imo it's better to define a signal in the receiver which then does the thread context switch.

              Qt Online Installer direct download: https://download.qt.io/official_releases/online_installers/
              Visit the Qt Academy at https://academy.qt.io/catalog

              1 Reply Last reply
              1
              • A Online
                A Online
                Axel Spoerl
                Moderators
                wrote 29 days ago last edited by
                #7

                In order to emit a signal or use QMetaObject::invokeMethod() from another thread, it doesn't technically have to be a QThread. What's required is an event loop and the emitter / invoker to inherit from QObject. But if you develop an application with Qt, why not use QThread anyway?

                We've seen an implementation in this topic, that circumvents missing QObject inheritance / event loop. It implements methods in a QObject wrapping a QMetaObject::invokeMethod() call on itself. The caller just calls the wrapper from another thread. While it might technically work, I would clearly not recommend it. Instead, make the caller inherit from QObject and let it live in another QThread. All problems solved cleanly.

                Software Engineer
                The Qt Company, Oslo

                J 1 Reply Last reply 29 days ago
                1
                • A Axel Spoerl
                  29 days ago

                  In order to emit a signal or use QMetaObject::invokeMethod() from another thread, it doesn't technically have to be a QThread. What's required is an event loop and the emitter / invoker to inherit from QObject. But if you develop an application with Qt, why not use QThread anyway?

                  We've seen an implementation in this topic, that circumvents missing QObject inheritance / event loop. It implements methods in a QObject wrapping a QMetaObject::invokeMethod() call on itself. The caller just calls the wrapper from another thread. While it might technically work, I would clearly not recommend it. Instead, make the caller inherit from QObject and let it live in another QThread. All problems solved cleanly.

                  J Offline
                  J Offline
                  JonB
                  wrote 29 days ago last edited by
                  #8

                  @Axel-Spoerl said in Invoking a slot from a non-Qt thread:

                  But if you develop an application with Qt, why not use QThread anyway?

                  I agree. But don't you think Mr @Perdrix is going to say "because it's already in someone else's code which I don't want to change but instead work with"? :)

                  1 Reply Last reply
                  1
                  • P Offline
                    P Offline
                    Perdrix
                    wrote 29 days ago last edited by
                    #9

                    The application was not developed using Qt it was developed using MFC. We have converted it to Qt over the last two to three years (it was a pretty large job). Where it was helpful and expedient we did use QThreads, but there are other bits of threading that we've not (yet) got round to...

                    1 Reply Last reply
                    1
                    • A Online
                      A Online
                      Axel Spoerl
                      Moderators
                      wrote 29 days ago last edited by
                      #10

                      Sounds like squeezing toothpaste back into the tube.
                      I'd probably go for an interface class, living inside the std::thread, inheriting from QObject and running its own QEventLoop.
                      That class can provide wrappers to either invoke methods in other threads, or emit signals.
                      In the moment you could replace the whatever thread with a QThread, you can untangle the interface class and do the calls directly.

                      Software Engineer
                      The Qt Company, Oslo

                      S 1 Reply Last reply 27 days ago
                      0
                      • J.HilkJ Offline
                        J.HilkJ Offline
                        J.Hilk
                        Moderators
                        wrote 27 days ago last edited by
                        #11

                        I haven't tried anything, but can't you simply pass a qt signal als callback function? Any connects won't auto default to QtQueuedConnection as there's no thread info due to no QThread but you can manage that manually


                        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
                        • A Axel Spoerl
                          29 days ago

                          Sounds like squeezing toothpaste back into the tube.
                          I'd probably go for an interface class, living inside the std::thread, inheriting from QObject and running its own QEventLoop.
                          That class can provide wrappers to either invoke methods in other threads, or emit signals.
                          In the moment you could replace the whatever thread with a QThread, you can untangle the interface class and do the calls directly.

                          S Offline
                          S Offline
                          SimonSchroeder
                          wrote 27 days ago last edited by
                          #12

                          @Axel-Spoerl said in Invoking a slot from a non-Qt thread:

                          I'd probably go for an interface class, living inside the std::thread, inheriting from QObject and running its own QEventLoop.

                          From what I understand only the calling thread does not have anything Qt-based. In order to emit a signals there is no need to start an event loop inside that non-Qt thread. Only a receiving slot would require an event loop. Or am I wrong about this?

                          The quickest way would certainly be using invokeMethod. However, if you can (and are willing to) using signals is always better. If you don't want to introduce any Qt into that thread (yet) you can have a regular C++ function inside some existing Qt code and call that. This function can either use invokeMethod or even emit a signal for your.

                          If it is inevitable to keep Qt out of your thread (in the long run) it makes sense to create something derived from QObject to be used inside your non-Qt thread. Then you can emit a signal using this object. I don't think you need anything special in the calling thread. emit is just a Qt keyword that gets removed by the preprocessor. From the compiler's point of view emitting a signal is just calling a regular member function. (The member function for the signal is generated by moc.) You need to be careful about object lifetimes. The calling object needs to live long enough for the slot to be executed. If the calling or receiving object in a connect statement is deleted, all queued slot invocations are also removed. Also, as your non-Qt thread does not have an event loop you cannot use deleteLater() to delete the object. If you cannot guarantee that your non-Qt thread runs long enough for the slot to be executed (or rather at least started) inside the Qt thread (and thus cannot guarantee a long lifetime for the QObject-derived object) using invokeMethod is the safest way. Maybe it even makes the most sense to use invokeMethod if you don't rely on member variables of the calling object, but instead hand over all data necessary for the slot as function arguments. It certainly avoid thinking about object lifetimes (and thread lifetimes).

                          1 Reply Last reply
                          0

                          1/12

                          3 May 2025, 10:11

                          • Login

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