c++ 为什么相同的信号需要连接到主电路插槽方法才能触发?

smdncfj3  于 2023-06-07  发布在  其他
关注(0)|答案(1)|浏览(107)

我有两个线程,一个主线程和一个子线程,主线程中的一个信号分别连接到主线程和子线程中的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
oxcyiej7

oxcyiej71#

我想我已经找到了答案,因为在主线程的析构函数中,程序执行得太快,信号发出,程序还没来得及执行就被关闭了。

相关问题