我有两个线程,一个主线程和一个子线程,主线程中的一个信号分别连接到主线程和子线程中的slot方法。
我在主线程的析构函数中发出这个信号,并希望在主线程GUI窗口关闭时触发它。
我发现,如果我不把这个信号与主线程的slot方法连接起来,子线程的slot方法也不能触发。
备注:
- 下面的代码中省略了一些细节
- 信号:
testslot
- 插槽:
testsig
其他的在这段代码中并不重要,重要的是:
connect(this,
&Widget::testsig,
m_check_serial_worker,
&Check_Serial_Monitor_Worker::testslot);
connect(this,
&Widget::testsig,
this,
&Widget::testslot);
主线程:
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");
}
子线程:
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");
}
相同的信号分别连接子线程和主线程中的槽方法。如果主线程未连接,则子线程将不会执行。这是为什么呢?
环境:
- 系统:Windows 11
- Qt版本:5.9.0
1条答案
按热度按时间oxcyiej71#
我想我已经找到了答案,因为在主线程的析构函数中,程序执行得太快,信号发出,程序还没来得及执行就被关闭了。