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 issue of one thread calling another thread
Forum Updated to NodeBB v4.3 + New Features

QThread issue of one thread calling another thread

Scheduled Pinned Locked Moved Unsolved General and Desktop
9 Posts 4 Posters 508 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.
  • M Offline
    M Offline
    micha_eleric
    wrote on last edited by
    #1

    main.cpp

    #include "CClass2.h"
    
    int main(int argc, char *argv[])
    {
        QApplication a(argc, argv);
    
        CClass1 c1; 
        CClass2 c2; 
        CClass3 c3; 
    
        c1.SetC2(&c2);
        c3.SetC2(&c2);
    
        c2.SetC1(&c1);
        c2.SetC3(&c3);
    
        c2.StartThreads();
    
        c1.show();
        return a.exec();
    }
    
    

    CClass1.h

    #ifndef CCLASS1_H
    #define CCLASS1_H
    
    #include <QObject>
    #include "MainWindow.h"
    #include <QApplication>
    
    class CClass2;
    
    class CClass1 : public QMainWindow
    {Q_OBJECT
    //?? data
    private:
        // data
        Ui_MainWindow *m_ui;
        CClass2 *m_c2; 
    
    public:
        // constructor
        CClass1(QWidget *parent = 0);
        // destructor
        virtual ~CClass1();
    
        // get/set
        void SetC2(CClass2 *c2);
    
        // functions
        void Button();
    
    };
    
    #endif // CCLASS1_H
    

    CClass.cpp

    #include "CClass1.h"
    #include "CClass2.h"
    
    CClass1::CClass1(QWidget *parent): QMainWindow(parent)
    {
        m_ui = new Ui_MainWindow();
        m_ui->setupUi(this);
        connect(m_ui->pushButton, &QPushButton::clicked, this, &CClass1::Button);
    }
    
    CClass1::~CClass1()
    {
    
    }
    
    void CClass1::SetC2(CClass2 *c2)
    {
        m_c2 = c2;
    }
    
    void CClass1::Button()
    {
        m_c2->CallButton();
    }
    

    CClass2.h

    #ifndef CCLASS2_H
    #define CCLASS2_H
    
    #include <QObject>
    #include "CClass1.h"
    #include "CClass3.h"
    #include <QThread>
    
    class CClass2 : public QThread
    {
        Q_OBJECT
        CClass1 *m_c1;
        CClass3 *m_c3;
        QThread* m_threadC1;
        QThread* m_threadC3; 
    
    public:
        // constructor
        CClass2();
        // destructor
        virtual ~CClass2();
    
        //get/set
        void SetC1(CClass1 *c1);
        void SetC3(CClass3 * c3);
    
        // function
        void StartThreads();
        void CallButton();
    
    signals:
        void EmitButton();
    
    };
    
    #endif // CCLASS2_H
    

    CClass2.cpp

    #include "CClass2.h"
    
    CClass2::CClass2() : QThread()
    {
        m_threadC3 = new QThread();
    }
    
    CClass2::~CClass2()
    {
    
    }
    
    void CClass2::SetC1(CClass1 *c1) 
    {
        m_c1 = c1;
    }
    
    void CClass2::SetC3(CClass3 * c3) /
    {
        m_c3 = c3;
        m_c3->moveToThread(m_threadC3);
        connect(m_c3, &CClass3::finished, m_threadC3, &QThread::quit);
        connect(m_c3, &CClass3::finished, m_c3, &CClass3::deleteLater);
        connect(m_threadC3, &QThread::finished, m_threadC3, &QThread::deleteLater);
                m_c3->start();
    }
    
    void CClass2::StartThreads()
    {
        connect(this, &CClass2::EmitButton, m_c3, &CClass3::ReceiveButton);
    }
    
    void CClass2::CallButton()
    {
        emit EmitButton();
    }
    

    CClass3.h

    #ifndef CCLASS3_H
    #define CCLASS3_H
    
    #include <QThread>
    #include <iostream>
    
    class CClass2;
    
    class CClass3 : public QThread
    {
    private:
        // data
        CClass2 *m_c2; 
    
    public:
        // constructor
        CClass3();
        // destructor
        virtual ~CClass3();
    
        // get/set
        void SetC2(CClass2 *c2);
    
    public slots:
        void ReceiveButton();
    
    };
    
    #endif // CCLASS3_H
    

    CClass3.cpp

    #include "CClass2.h"
    #include "CClass3.h"
    
    CClass3::CClass3() : QThread()
    {
        std::cout << "CClass3\n" << std::flush;
    }
    
    CClass3::~CClass3()
    {
    
    }
    
    void CClass3::SetC2(CClass2 *c2)
    {
        m_c2 = c2;
    }
    
    void CClass3::ReceiveButton()
    {
        std::cout << "button\n" << std::flush;
    }
    

    CClass3::ReceiveButton() is not called.
    what have i done wrong?

    Christian EhrlicherC C 2 Replies Last reply
    0
    • M micha_eleric

      main.cpp

      #include "CClass2.h"
      
      int main(int argc, char *argv[])
      {
          QApplication a(argc, argv);
      
          CClass1 c1; 
          CClass2 c2; 
          CClass3 c3; 
      
          c1.SetC2(&c2);
          c3.SetC2(&c2);
      
          c2.SetC1(&c1);
          c2.SetC3(&c3);
      
          c2.StartThreads();
      
          c1.show();
          return a.exec();
      }
      
      

      CClass1.h

      #ifndef CCLASS1_H
      #define CCLASS1_H
      
      #include <QObject>
      #include "MainWindow.h"
      #include <QApplication>
      
      class CClass2;
      
      class CClass1 : public QMainWindow
      {Q_OBJECT
      //?? data
      private:
          // data
          Ui_MainWindow *m_ui;
          CClass2 *m_c2; 
      
      public:
          // constructor
          CClass1(QWidget *parent = 0);
          // destructor
          virtual ~CClass1();
      
          // get/set
          void SetC2(CClass2 *c2);
      
          // functions
          void Button();
      
      };
      
      #endif // CCLASS1_H
      

      CClass.cpp

      #include "CClass1.h"
      #include "CClass2.h"
      
      CClass1::CClass1(QWidget *parent): QMainWindow(parent)
      {
          m_ui = new Ui_MainWindow();
          m_ui->setupUi(this);
          connect(m_ui->pushButton, &QPushButton::clicked, this, &CClass1::Button);
      }
      
      CClass1::~CClass1()
      {
      
      }
      
      void CClass1::SetC2(CClass2 *c2)
      {
          m_c2 = c2;
      }
      
      void CClass1::Button()
      {
          m_c2->CallButton();
      }
      

      CClass2.h

      #ifndef CCLASS2_H
      #define CCLASS2_H
      
      #include <QObject>
      #include "CClass1.h"
      #include "CClass3.h"
      #include <QThread>
      
      class CClass2 : public QThread
      {
          Q_OBJECT
          CClass1 *m_c1;
          CClass3 *m_c3;
          QThread* m_threadC1;
          QThread* m_threadC3; 
      
      public:
          // constructor
          CClass2();
          // destructor
          virtual ~CClass2();
      
          //get/set
          void SetC1(CClass1 *c1);
          void SetC3(CClass3 * c3);
      
          // function
          void StartThreads();
          void CallButton();
      
      signals:
          void EmitButton();
      
      };
      
      #endif // CCLASS2_H
      

      CClass2.cpp

      #include "CClass2.h"
      
      CClass2::CClass2() : QThread()
      {
          m_threadC3 = new QThread();
      }
      
      CClass2::~CClass2()
      {
      
      }
      
      void CClass2::SetC1(CClass1 *c1) 
      {
          m_c1 = c1;
      }
      
      void CClass2::SetC3(CClass3 * c3) /
      {
          m_c3 = c3;
          m_c3->moveToThread(m_threadC3);
          connect(m_c3, &CClass3::finished, m_threadC3, &QThread::quit);
          connect(m_c3, &CClass3::finished, m_c3, &CClass3::deleteLater);
          connect(m_threadC3, &QThread::finished, m_threadC3, &QThread::deleteLater);
                  m_c3->start();
      }
      
      void CClass2::StartThreads()
      {
          connect(this, &CClass2::EmitButton, m_c3, &CClass3::ReceiveButton);
      }
      
      void CClass2::CallButton()
      {
          emit EmitButton();
      }
      

      CClass3.h

      #ifndef CCLASS3_H
      #define CCLASS3_H
      
      #include <QThread>
      #include <iostream>
      
      class CClass2;
      
      class CClass3 : public QThread
      {
      private:
          // data
          CClass2 *m_c2; 
      
      public:
          // constructor
          CClass3();
          // destructor
          virtual ~CClass3();
      
          // get/set
          void SetC2(CClass2 *c2);
      
      public slots:
          void ReceiveButton();
      
      };
      
      #endif // CCLASS3_H
      

      CClass3.cpp

      #include "CClass2.h"
      #include "CClass3.h"
      
      CClass3::CClass3() : QThread()
      {
          std::cout << "CClass3\n" << std::flush;
      }
      
      CClass3::~CClass3()
      {
      
      }
      
      void CClass3::SetC2(CClass2 *c2)
      {
          m_c2 = c2;
      }
      
      void CClass3::ReceiveButton()
      {
          std::cout << "button\n" << std::flush;
      }
      

      CClass3::ReceiveButton() is not called.
      what have i done wrong?

      Christian EhrlicherC Offline
      Christian EhrlicherC Offline
      Christian Ehrlicher
      Lifetime Qt Champion
      wrote on last edited by
      #2

      When you want to use signals and slots the called thread must be run an event loop as explained in the documentation - Queued signals are placed in the thread's event loop - when there is none it can't work.

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

      M 1 Reply Last reply
      3
      • Christian EhrlicherC Christian Ehrlicher

        When you want to use signals and slots the called thread must be run an event loop as explained in the documentation - Queued signals are placed in the thread's event loop - when there is none it can't work.

        M Offline
        M Offline
        micha_eleric
        wrote on last edited by
        #3

        @Christian-Ehrlicher read the document many times, still not fully understanding how to use qthreads properly. any other sites you recommend?

        Christian EhrlicherC 1 Reply Last reply
        0
        • M micha_eleric

          main.cpp

          #include "CClass2.h"
          
          int main(int argc, char *argv[])
          {
              QApplication a(argc, argv);
          
              CClass1 c1; 
              CClass2 c2; 
              CClass3 c3; 
          
              c1.SetC2(&c2);
              c3.SetC2(&c2);
          
              c2.SetC1(&c1);
              c2.SetC3(&c3);
          
              c2.StartThreads();
          
              c1.show();
              return a.exec();
          }
          
          

          CClass1.h

          #ifndef CCLASS1_H
          #define CCLASS1_H
          
          #include <QObject>
          #include "MainWindow.h"
          #include <QApplication>
          
          class CClass2;
          
          class CClass1 : public QMainWindow
          {Q_OBJECT
          //?? data
          private:
              // data
              Ui_MainWindow *m_ui;
              CClass2 *m_c2; 
          
          public:
              // constructor
              CClass1(QWidget *parent = 0);
              // destructor
              virtual ~CClass1();
          
              // get/set
              void SetC2(CClass2 *c2);
          
              // functions
              void Button();
          
          };
          
          #endif // CCLASS1_H
          

          CClass.cpp

          #include "CClass1.h"
          #include "CClass2.h"
          
          CClass1::CClass1(QWidget *parent): QMainWindow(parent)
          {
              m_ui = new Ui_MainWindow();
              m_ui->setupUi(this);
              connect(m_ui->pushButton, &QPushButton::clicked, this, &CClass1::Button);
          }
          
          CClass1::~CClass1()
          {
          
          }
          
          void CClass1::SetC2(CClass2 *c2)
          {
              m_c2 = c2;
          }
          
          void CClass1::Button()
          {
              m_c2->CallButton();
          }
          

          CClass2.h

          #ifndef CCLASS2_H
          #define CCLASS2_H
          
          #include <QObject>
          #include "CClass1.h"
          #include "CClass3.h"
          #include <QThread>
          
          class CClass2 : public QThread
          {
              Q_OBJECT
              CClass1 *m_c1;
              CClass3 *m_c3;
              QThread* m_threadC1;
              QThread* m_threadC3; 
          
          public:
              // constructor
              CClass2();
              // destructor
              virtual ~CClass2();
          
              //get/set
              void SetC1(CClass1 *c1);
              void SetC3(CClass3 * c3);
          
              // function
              void StartThreads();
              void CallButton();
          
          signals:
              void EmitButton();
          
          };
          
          #endif // CCLASS2_H
          

          CClass2.cpp

          #include "CClass2.h"
          
          CClass2::CClass2() : QThread()
          {
              m_threadC3 = new QThread();
          }
          
          CClass2::~CClass2()
          {
          
          }
          
          void CClass2::SetC1(CClass1 *c1) 
          {
              m_c1 = c1;
          }
          
          void CClass2::SetC3(CClass3 * c3) /
          {
              m_c3 = c3;
              m_c3->moveToThread(m_threadC3);
              connect(m_c3, &CClass3::finished, m_threadC3, &QThread::quit);
              connect(m_c3, &CClass3::finished, m_c3, &CClass3::deleteLater);
              connect(m_threadC3, &QThread::finished, m_threadC3, &QThread::deleteLater);
                      m_c3->start();
          }
          
          void CClass2::StartThreads()
          {
              connect(this, &CClass2::EmitButton, m_c3, &CClass3::ReceiveButton);
          }
          
          void CClass2::CallButton()
          {
              emit EmitButton();
          }
          

          CClass3.h

          #ifndef CCLASS3_H
          #define CCLASS3_H
          
          #include <QThread>
          #include <iostream>
          
          class CClass2;
          
          class CClass3 : public QThread
          {
          private:
              // data
              CClass2 *m_c2; 
          
          public:
              // constructor
              CClass3();
              // destructor
              virtual ~CClass3();
          
              // get/set
              void SetC2(CClass2 *c2);
          
          public slots:
              void ReceiveButton();
          
          };
          
          #endif // CCLASS3_H
          

          CClass3.cpp

          #include "CClass2.h"
          #include "CClass3.h"
          
          CClass3::CClass3() : QThread()
          {
              std::cout << "CClass3\n" << std::flush;
          }
          
          CClass3::~CClass3()
          {
          
          }
          
          void CClass3::SetC2(CClass2 *c2)
          {
              m_c2 = c2;
          }
          
          void CClass3::ReceiveButton()
          {
              std::cout << "button\n" << std::flush;
          }
          

          CClass3::ReceiveButton() is not called.
          what have i done wrong?

          C Offline
          C Offline
          ChrisW67
          wrote on last edited by
          #4

          @micha_eleric said in QThread issue of one thread calling another thread:

          void CClass2::SetC3(CClass3 * c3) /
          {
              m_c3 = c3;
              m_c3->moveToThread(m_threadC3);
              connect(m_c3, &CClass3::finished, m_threadC3, &QThread::quit);
              connect(m_c3, &CClass3::finished, m_c3, &CClass3::deleteLater);
              connect(m_threadC3, &QThread::finished, m_threadC3, &QThread::deleteLater);
                      m_c3->start();
          }
          

          Surely you mean to start m_threadC3? Actually this is very confused. You have m_threadC3, presumably a QThread, and CClass3 which is also a QThread. Have a closer read of the example near the top of the docs that @Christian-Ehrlicher linked to. Neither the worker nor the controller is a QThread object.

          There are also these notes How to Really, Truly Use QThreads that date from Qt 4 before the Qt 5 documentation started to change to reflect much the same advice.

          1 Reply Last reply
          0
          • M micha_eleric

            @Christian-Ehrlicher read the document many times, still not fully understanding how to use qthreads properly. any other sites you recommend?

            Christian EhrlicherC Offline
            Christian EhrlicherC Offline
            Christian Ehrlicher
            Lifetime Qt Champion
            wrote on last edited by
            #5

            @micha_eleric said in QThread issue of one thread calling another thread:

            any other sites you recommend?

            No

            As I said - it's not about threads but about slots - you must run an event loop in your thread so slots can be called. You don't so no slots.

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

            M 1 Reply Last reply
            3
            • Christian EhrlicherC Christian Ehrlicher

              @micha_eleric said in QThread issue of one thread calling another thread:

              any other sites you recommend?

              No

              As I said - it's not about threads but about slots - you must run an event loop in your thread so slots can be called. You don't so no slots.

              M Offline
              M Offline
              micha_eleric
              wrote on last edited by
              #6

              @Christian-Ehrlicher thought

              class CClass1 : public QMainWindow
              

              was and event loop

              not the slot you mean?

              public slots:
                  void ReceiveButton();
              
              JonBJ 1 Reply Last reply
              0
              • M micha_eleric

                @Christian-Ehrlicher thought

                class CClass1 : public QMainWindow
                

                was and event loop

                not the slot you mean?

                public slots:
                    void ReceiveButton();
                
                JonBJ Online
                JonBJ Online
                JonB
                wrote on last edited by
                #7

                @micha_eleric
                Have you read the basic explanation in https://doc.qt.io/qt-6/qthread.html#details (the link @Christian-Ehrlicher gave you)?

                A QThread object manages one thread of control within the program. QThreads begin executing in run(). By default, run() starts the event loop by calling exec() and runs a Qt event loop inside the thread.

                M 1 Reply Last reply
                1
                • JonBJ JonB

                  @micha_eleric
                  Have you read the basic explanation in https://doc.qt.io/qt-6/qthread.html#details (the link @Christian-Ehrlicher gave you)?

                  A QThread object manages one thread of control within the program. QThreads begin executing in run(). By default, run() starts the event loop by calling exec() and runs a Qt event loop inside the thread.

                  M Offline
                  M Offline
                  micha_eleric
                  wrote on last edited by
                  #8

                  @JonB yes, many times

                  1 Reply Last reply
                  0
                  • M Offline
                    M Offline
                    micha_eleric
                    wrote on last edited by
                    #9

                    @micha_eleric said in QThread issue of one thread calling another thread:
                    changing

                    class CClass3 : public QThread
                    

                    to

                    class CClass3 : public QObject
                    

                    fixed issue, along with issues raised from change

                    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