Question

I'm using a separate thread for serial port communication. This thread should launch when we want to connect with serial port and finish when there was an error/disconnection.

The issue is that if the thread has finished once, it doesn't relaunch the next time we want to reconnect.

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();
    }
}

It seems that the thread doesn't finish properly, but I've already checked the thread is not running! Then the program finish unexpectedly.


Solution:

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

Solution

deleteLater() posts an event to the event queue (like a repaint event, a timer event or a network event). If the event is processed it deletes the object. If there is no event loop your object isn’t deleted.

You are quitting the thread first which cause your object not to be deteted and consequently your destructor does not get called.

You should connect finished() signal of the thread to a slot to disconnect :

QObject::connect(&thread,SIGNAL(finished()),serialio,SLOT(disconnectSP())); 

void SerialIO::disconnectSP()
{ 
    serial->close();
}

Also there is no need to call deleteLater() as you are newing your object once.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top