我正在使用单独的线程进行串口通信。当我们想要连接串口并在出现错误/断开连接时完成此线程。
问题是如果线程已经完成一次,则下次我们想要重新连接时它不会重新启动。
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()));
答案 0 :(得分:3)
deleteLater()
将事件发布到事件队列(如重绘事件,计时器事件或网络事件)。如果处理事件,则删除该对象。如果没有事件循环,则不删除对象。
您首先退出线程会导致您的对象不被拒绝,因此您的析构函数不会被调用。
您应该将线程的finished()
信号连接到要断开连接的插槽:
QObject::connect(&thread,SIGNAL(finished()),serialio,SLOT(disconnectSP()));
void SerialIO::disconnectSP()
{
serial->close();
}
此外,您无需拨打deleteLater()
,因为您需要修改一次对象。