如何在Qt中重新启动线程

How to relaunch a thread in Qt?

本文关键字:重新启动 线程 Qt      更新时间:2023-10-16

我使用一个单独的线程进行串口通信。这个线程应该在我们想要连接串行端口时启动,并在出现错误/断开连接时完成。

问题是,如果线程已经完成了一次,它不会重新启动下一次我们想要重新连接。

SerialIO::SerialIO(SettingsDialog *settings) :  //Worker. Extends QObject
    settings(settings)
{
    serial = new QSerialPort(this);
}
SerialIO::~SerialIO()
{
    serial->close();  
    //something else?  
}

/* PUBLIC SLOT */
void SerialIO::connectSP()
{ 
    /* connects with some port, if not succesfull, emits an error signal */ 
}

MainWindow::MainWindow(QWidget *parent)
    : QWidget(parent)
{
    //...
    serialio = new SerialIO(settings);
    serialio->moveToThread(&thread);  
    QObject::connect(&thread,SIGNAL(started()),serialio,SLOT(connectSP()));
    QObject::connect(&thread,SIGNAL(finished()),serialio,SLOT(deleteLater()));  
    QObject::connect(serialio,SIGNAL(error(const QString)),this,SLOT(handleError(const QString&)));      
    //...
}
void MainWindow::connect()   
{
    if(!thread.isRunning()){              
        thread.start();
    }
}
void MainWindow::handleError(const QString &msg){
    QMessageBox::information(this, "Error", msg);
    if(thread.isRunning()){
        thread.quit();
        thread.wait();
    }
}

似乎线程没有正确完成,但我已经检查了线程没有运行!然后程序意外结束。


解决方案:

QObject::connect(&thread,SIGNAL(started()),serialio,SLOT(connectSP()));
QObject::connect(&thread,SIGNAL(finished()),serialio,SLOT(disconnectSP()));
QObject::connect(serialio,SIGNAL(bye()),&thread,SLOT(quit()));

deleteLater()将事件发送到事件队列(如重绘事件,计时器事件或网络事件)。如果事件被处理,它将删除对象。如果没有事件循环,对象不会被删除。

你先退出线程,导致你的对象不被检测,因此你的析构函数不会被调用。

您应该将线程的finished()信号连接到插槽以断开连接:

QObject::connect(&thread,SIGNAL(finished()),serialio,SLOT(disconnectSP())); 
void SerialIO::disconnectSP()
{ 
    serial->close();
}

也没有必要调用deleteLater(),因为你只更新一次对象。