2013-12-11 3 views
2

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

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 секунд). Каков правильный способ сделать это?

ответ

1

Другой метод для ожидания, не создавая дополнительную функцию:

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

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

+0

но это может сделать странные вещи, когда вещи удаляются –

+0

То есть, когда что-то еще удаляет SocketIO из цикла событий? –

+1

Да, когда кто-то делает 'deleteLater' на этом объекте, то после того, как цикл' this' будет недействительным -> неопределенное поведение, выполните 'while (time.elapsed() <15000) QCoreApplication :: processEvents (QEventLoop :: AllEvents, 15000-time.elapsed()); 'будет безопаснее –

4

Как об этом подходе:

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() слот под названием.

Смежные вопросы