I have two threads, a main thread and a sub-thread, and a signal in the main thread that's connected to the slot method in the main thread and the sub-thread respectively.
I emit this signal in the destructor of the main thread and want to trigger it when the main thread GUI window is closed.
I found that if I don't connect this signal with the main thread's slot method, the child thread's slot method can't trigger either.
Notes:
Some details are omitted in the following code
Signal:
testslot
Slot:
testsig
Others are not important in this code, the important is:
connect(this,
&Widget::testsig,
m_check_serial_worker,
&Check_Serial_Monitor_Worker::testslot);
connect(this,
&Widget::testsig,
this,
&Widget::testslot);
Main thread:
Widget::Widget(QWidget *parent) :
QWidget(parent),
ui(new Ui::Widget)
{
ui->setupUi(this);
this->setWindowTitle("bootloader");
Init_ComBoxs();
Init_Card_Info_List();
m_check_serial_worker = new Check_Serial_Monitor_Worker();
m_check_serial_worker->moveToThread(&m_check_serial_thread);
m_serial_comm_worker = new Serial_Comm_Worker();
m_serial_comm_worker->moveToThread(&m_serial_comm_thread);
connect(m_check_serial_worker,
&Check_Serial_Monitor_Worker::Have_Change_Serial,
this,&Widget::Update_Serial_List,
Qt::QueuedConnection);
connect(&m_check_serial_thread,&QThread::started,
m_check_serial_worker,&Check_Serial_Monitor_Worker::Start_Check);
connect(&m_serial_comm_thread, &QThread::finished,
m_serial_comm_worker, &QObject::deleteLater);
connect(&m_check_serial_thread,&QThread::finished,
m_check_serial_worker,&QObject::deleteLater);
connect(ui->operate_serial_switch_btn,&QPushButton::clicked,
this,&Widget::On_Operate_Serial_Switch_Btn_Clicked);
connect(ui->sel_dir_toolbtn,&QToolButton::clicked,
this,&Widget::On_Sel_Dir_Toolbtn_Clicked);
bool cnnret = connect(this,&Widget::Stop_Serial_Monitor_Thread,
m_check_serial_worker,&Check_Serial_Monitor_Worker::Stop_Cur_Thread,
Qt::QueuedConnection);
if(!cnnret){
Custom_Tools::Print("connect failed");
}
m_serial_comm_thread.start();
m_check_serial_thread.start();
connect(this,&Widget::testsig,
m_check_serial_worker,&Check_Serial_Monitor_Worker::testslot);
connect(this,&Widget::testsig,this,&Widget::testslot);
}
Widget::~Widget()
{
emit testsig();
emit Stop_Serial_Monitor_Thread();
if(ui->operate_serial_switch_btn->text() == QString("CLOSE")){
Operator_Serial_Switch();
}
m_check_serial_thread.quit();
m_check_serial_thread.wait();
m_serial_comm_thread.quit();
m_serial_comm_thread.wait();
delete ui;
}
void Widget::testslot()
{
Custom_Tools::Print("test slot frome main thread");
}
Child thread:
void Check_Serial_Monitor_Worker::Stop_Cur_Thread()
{
Custom_Tools::Print("Quit Slot");
m_timer->stop();
}
void Check_Serial_Monitor_Worker::Start_Check()
{
Do_Work();
open_flag = true;
m_timer = new QTimer;
m_timer->setTimerType(Qt::PreciseTimer);
connect(m_timer,&QTimer::timeout,this,&Check_Serial_Monitor_Worker::Do_Work);
m_timer->start(5000);
m_odd_serial_list.clear();
}
void Check_Serial_Monitor_Worker::Do_Work()
{
QStringList tmp_str_list;
tmp_str_list.clear();
foreach (const QSerialPortInfo &info, QSerialPortInfo::availablePorts()) {
tmp_str_list += info.portName();
}
if(tmp_str_list != m_odd_serial_list){
m_odd_serial_list = tmp_str_list;
Custom_Tools::Print("Update available serial port!");
emit Have_Change_Serial(tmp_str_list);
}
Custom_Tools::Print("Check Serials!");
}
void Check_Serial_Monitor_Worker::testslot()
{
Custom_Tools::Print("test emit from child thread");
}
The same signal connects the sub-thread and the slot method in the main thread respectively. If the main thread is not connected, the sub-thread will not execute. Why is this ?
Environment:
- System: Windows 11
- Qt version: 5.9.0