Подождать несколько секунд в Qt

Мои знания о потоках в Qt довольно ограничены, и теперь у меня есть проблема, которая, похоже, связана с потоками. Я использую QextSerialPort для связи через UART. Мой класс для последовательной связи выглядит так (раздет до минимума):

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
}

Проблема ждет 15 секунд в initialize() метод без блокировки последовательного ввода. Я старался

QThread::sleep(15)

и даже

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

Но с обеих попыток я перестал получать серийные данные (onDataAvailable больше не вызывался в течение этих 15 секунд). Как правильно это сделать?

2 ответа

Решение

Еще один метод ожидания без создания дополнительной функции:

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

Примечание: если что-то удаляет serialIO с deleteLater (при обработке какого-либо события / сигнала, полученного во время ожидания, возможно, от вашего последовательного входа) у вас будут удалены и недействительны this после завершения цикла Если это может привести к реальной ситуации в вашем приложении, лучше использовать отдельный слот для выполнения после таймера, как ответ @vahancho.

Как насчет этого подхода:

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

    // wait for 15 s
    QTimer::singleShot(15000, this, SLOT(onTimer()));
}

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

void SerialIO::onTimer()
{
    // do something else
}

Он не блокирует события, и вы получите onDataAvailable() слот называется.

Другие вопросы по тегам