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. Can an object living in one thread emit a signal from another thread?

Can an object living in one thread emit a signal from another thread?

Scheduled Pinned Locked Moved Unsolved General and Desktop
8 Posts 6 Posters 2.8k 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.
  • R Offline
    R Offline
    rrd0
    wrote on last edited by rrd0
    #1

    I have an object a created in the main thread, where its signals are connected to slots of other object, b, that also lives in the main thread.

    Then I create an object c and move it to a worker thread, where it will periodically access object a through a pointer, change its state and emit its signals.

    Here is the code:

    (Note: some lines were purposely ignored to keep the example short)

    class A : public QObject
    {
        Q_OBJECT
        friend class C;
    signals:
        void sigA();
    private:
        quint8 _m1;
        quint8 _m2;
    };
    
    class B : public QObject
    {
        Q_OBJECT
    public slots:
        void slotB();
    };
    
    class C : public QObject
    {
        Q_OBJECT
    public:
        C(A* a) : _a{a}, _timer{new QTimer{this}}
        {
            _timer->setInterval(5);
            connect(_timer, &QTimer::timeout, this, &C::doSomeWork);
        }
    
    public slots:
        void start() { _timer->start(); }
    
    private slots:
        void doSomeWork()
        {
            // update members of `a`
            emit _a->sigA();
            // ...
        }
    
    private:
        A* _a;
        QTimer* _timer;
    };
    
    int main(int argc, char* argv[])
    {
        QApplication app(argc, argv);
    
        A* a {new A};
        B* b {new B};
        QObject::connect(a, &A::sigA, b, &B::slotB);
    
        QThread* worker {new QThread};
        C* c {new C{a}};    
        c->moveToThread(worker);
    
        QObject::connect(worker, &QThread::started, c, &C::start);    
        worker->start();
    
        return app.exec();
    }
    

    I hope a signals, emitted from thread worker, will trigger b slots in main thread. And I hope I'll have no concurrency problems because a members are 8-bit sized.

    But c, that lives in thread worker, will be posting events in the main thread event queue. I'm not using any synchronization primitive, so I'm afraid I may run into problems.

    May I use the signal/slot mechanism the way I'm using in the code example? Am I doing something wrong?

    jsulmJ J.HilkJ 2 Replies Last reply
    0
    • Kent-DorfmanK Offline
      Kent-DorfmanK Offline
      Kent-Dorfman
      wrote on last edited by
      #2

      @rrd0 said in Can an object living in Thread A emit a signal from Thread B?:

      Then I create an object C and move it to a worker thread W, where it will access object A through a pointer, change its state and emit its signals.

      I think that is asking for trouble. Use the signal/slot mechanism exclusively. have C emit signals to slots in A. Don't access A members directly via its object pointer.

      If you meet the AI on the road, kill it.

      1 Reply Last reply
      4
      • R rrd0

        I have an object a created in the main thread, where its signals are connected to slots of other object, b, that also lives in the main thread.

        Then I create an object c and move it to a worker thread, where it will periodically access object a through a pointer, change its state and emit its signals.

        Here is the code:

        (Note: some lines were purposely ignored to keep the example short)

        class A : public QObject
        {
            Q_OBJECT
            friend class C;
        signals:
            void sigA();
        private:
            quint8 _m1;
            quint8 _m2;
        };
        
        class B : public QObject
        {
            Q_OBJECT
        public slots:
            void slotB();
        };
        
        class C : public QObject
        {
            Q_OBJECT
        public:
            C(A* a) : _a{a}, _timer{new QTimer{this}}
            {
                _timer->setInterval(5);
                connect(_timer, &QTimer::timeout, this, &C::doSomeWork);
            }
        
        public slots:
            void start() { _timer->start(); }
        
        private slots:
            void doSomeWork()
            {
                // update members of `a`
                emit _a->sigA();
                // ...
            }
        
        private:
            A* _a;
            QTimer* _timer;
        };
        
        int main(int argc, char* argv[])
        {
            QApplication app(argc, argv);
        
            A* a {new A};
            B* b {new B};
            QObject::connect(a, &A::sigA, b, &B::slotB);
        
            QThread* worker {new QThread};
            C* c {new C{a}};    
            c->moveToThread(worker);
        
            QObject::connect(worker, &QThread::started, c, &C::start);    
            worker->start();
        
            return app.exec();
        }
        

        I hope a signals, emitted from thread worker, will trigger b slots in main thread. And I hope I'll have no concurrency problems because a members are 8-bit sized.

        But c, that lives in thread worker, will be posting events in the main thread event queue. I'm not using any synchronization primitive, so I'm afraid I may run into problems.

        May I use the signal/slot mechanism the way I'm using in the code example? Am I doing something wrong?

        jsulmJ Offline
        jsulmJ Offline
        jsulm
        Lifetime Qt Champion
        wrote on last edited by
        #3
        This post is deleted!
        1 Reply Last reply
        0
        • R rrd0

          I have an object a created in the main thread, where its signals are connected to slots of other object, b, that also lives in the main thread.

          Then I create an object c and move it to a worker thread, where it will periodically access object a through a pointer, change its state and emit its signals.

          Here is the code:

          (Note: some lines were purposely ignored to keep the example short)

          class A : public QObject
          {
              Q_OBJECT
              friend class C;
          signals:
              void sigA();
          private:
              quint8 _m1;
              quint8 _m2;
          };
          
          class B : public QObject
          {
              Q_OBJECT
          public slots:
              void slotB();
          };
          
          class C : public QObject
          {
              Q_OBJECT
          public:
              C(A* a) : _a{a}, _timer{new QTimer{this}}
              {
                  _timer->setInterval(5);
                  connect(_timer, &QTimer::timeout, this, &C::doSomeWork);
              }
          
          public slots:
              void start() { _timer->start(); }
          
          private slots:
              void doSomeWork()
              {
                  // update members of `a`
                  emit _a->sigA();
                  // ...
              }
          
          private:
              A* _a;
              QTimer* _timer;
          };
          
          int main(int argc, char* argv[])
          {
              QApplication app(argc, argv);
          
              A* a {new A};
              B* b {new B};
              QObject::connect(a, &A::sigA, b, &B::slotB);
          
              QThread* worker {new QThread};
              C* c {new C{a}};    
              c->moveToThread(worker);
          
              QObject::connect(worker, &QThread::started, c, &C::start);    
              worker->start();
          
              return app.exec();
          }
          

          I hope a signals, emitted from thread worker, will trigger b slots in main thread. And I hope I'll have no concurrency problems because a members are 8-bit sized.

          But c, that lives in thread worker, will be posting events in the main thread event queue. I'm not using any synchronization primitive, so I'm afraid I may run into problems.

          May I use the signal/slot mechanism the way I'm using in the code example? Am I doing something wrong?

          J.HilkJ Offline
          J.HilkJ Offline
          J.Hilk
          Moderators
          wrote on last edited by
          #4

          @rrd0
          I principle, there should be no reason for problems.

          Connecting signals to signals is an established feature of Qt's Signal/Slot mechanism the fact that it in the end, will cross 3 different threads does't matter much.

          As long, as you do not force a DirectConnection at least. Also keep in mind, that your original signal will pass through 3 different event loops, so the execution of the final slot may very well be delayed by significant amount of time.


          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.

          R 1 Reply Last reply
          1
          • J.HilkJ J.Hilk

            @rrd0
            I principle, there should be no reason for problems.

            Connecting signals to signals is an established feature of Qt's Signal/Slot mechanism the fact that it in the end, will cross 3 different threads does't matter much.

            As long, as you do not force a DirectConnection at least. Also keep in mind, that your original signal will pass through 3 different event loops, so the execution of the final slot may very well be delayed by significant amount of time.

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

            @J.Hilk said in Can an object living in Thread A emit a signal from Thread B?:

            @rrd0
            I principle, there should be no reason for problems.

            Connecting signals to signals is an established feature of Qt's Signal/Slot mechanism the fact that it in the end, will cross 3 different threads does't matter much.

            But what about concurrent issues? I updated my question and added a code example. Can you please have a look?

            KroMignonK 1 Reply Last reply
            0
            • R rrd0

              @J.Hilk said in Can an object living in Thread A emit a signal from Thread B?:

              @rrd0
              I principle, there should be no reason for problems.

              Connecting signals to signals is an established feature of Qt's Signal/Slot mechanism the fact that it in the end, will cross 3 different threads does't matter much.

              But what about concurrent issues? I updated my question and added a code example. Can you please have a look?

              KroMignonK Offline
              KroMignonK Offline
              KroMignon
              wrote on last edited by
              #6

              @rrd0 I don't understand the meaning of this construct... why not move a in the worker thread?

              It is an old maxim of mine that when you have excluded the impossible, whatever remains, however improbable, must be the truth. (Sherlock Holmes)

              R 1 Reply Last reply
              0
              • KroMignonK KroMignon

                @rrd0 I don't understand the meaning of this construct... why not move a in the worker thread?

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

                @KroMignon said in Can an object living in one thread emit a signal from another thread?:

                @rrd0 I don't understand the meaning of this construct... why not move a in the worker thread?

                I'm actually trying to do that, but the problem I have is a little more complex than the example I wrote here. If a could keep a in the main thread it would be a lot easier for me.

                1 Reply Last reply
                0
                • SGaistS Offline
                  SGaistS Offline
                  SGaist
                  Lifetime Qt Champion
                  wrote on last edited by
                  #8

                  Hi,

                  Why exactly are you trying to emit a signal from an instance of class A in C ? That doesn't look clean and it's not the correct way to emit a signal. The purpose of a signal is to notify the outside that something has changed inside an object.

                  Interested in AI ? www.idiap.ch
                  Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

                  1 Reply Last reply
                  1

                  • Login

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