QThread issue of one thread calling another thread
-
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? -
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.
-
@Christian-Ehrlicher read the document many times, still not fully understanding how to use qthreads properly. any other sites you recommend?
-
@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.
-
@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.
-
@Christian-Ehrlicher thought
class CClass1 : public QMainWindow
was and event loop
not the slot you mean?
public slots: void ReceiveButton();
-
@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 callingexec()
and runs a Qt event loop inside the thread. -
@micha_eleric said in QThread issue of one thread calling another thread:
changingclass CClass3 : public QThread
to
class CClass3 : public QObject
fixed issue, along with issues raised from change