Search code examples
multithreadingqtqextserialport

waiting a few seconds in Qt


My knowledge of threading in Qt is rather limited, and I have a problem now that seems to be related to threading. I'm using QextSerialPort for communication over a uart. My class for serial communication looks like this (stripped to the minimum):

SerialIO::SerialIO() {
    port = new QextSerialPort("/dev/ttymxc1");
    connect(port, SIGNAL(readyRead()), this, SLOT(onDataAvailable()));
    port->setQueryMode(QextSerialPort::EventDriven);
    port->open(QIODevice::ReadWrite | QIODevice::Unbuffered);
    port->setBaudRate(BAUD115200);
    port->setFlowControl(FLOW_OFF);
    port->setParity(PAR_NONE);
    port->setDataBits(DATA_8);
    port->setStopBits(STOP_1);
}

void SerialIO::initialize() {
    // do something

    // wait for 15 s

    // do something else
}

void SerialIO::onDataAvailable() {
    // do something useful
}

The problem is waiting for 15 s in the initialize() method without blocking serial input. I tried

QThread::sleep(15)

and even

QTime time;
time.start();
while(time.elapsed() < 15000); // evil busy wait

But with both attempts, I stopped getting serial data (onDataAvailable was no longer called during those 15 seconds). What is the correct way to do this?


Solution

  • Another method for waiting without creating an extra function:

    void SerialIO::initialize() {
      // Code here
      QEventLoop loop;
      QTimer::singleShot(15000, &loop, SLOT(quit()));
      loop.exec();
      // Code here, executed after 15s
    }
    

    Note: If something deletes the serialIO with deleteLater (when processing some event/signal received during the wait, maybe from your serial input) you will have a deleted and invalid this after the loop quits. If this can be a real situation on your application, better use a separated slot to be executed after the timer like @vahancho's answer.