0

I'm using QTimer and timeout signal doesn't emit.

Here is my code:

    QTimer* receiveTimer = new QTimer();
    receiveTimer->setInterval(1000);
    connect(receiveTimer, SIGNAL(timeout()), this, SLOT(timeout()));

    QByteArray res;
    inWait = true;
    receiveTimer->start();

    qDebug() << "Before while";

    while (!res.contains("OK\r\n") && inWait)
        qDebug() << res.append(sPort->read(1));

    qDebug() << "After while";

    receiveTimer->stop();

At first, i had defined the timer at the class constructor, but it didn't worked either.

  • 4
    QTimer only works if the Qt event loop is running; it can't/won't work while your thread is stuck inside your own `while()` loop, because that prevents the Qt event loop from executing events. See details here: https://stackoverflow.com/questions/42279360/does-a-qtimer-object-run-in-a-separate-thread-what-is-its-mechanism/42311174#42311174 – Jeremy Friesner Aug 01 '19 at 15:33
  • so, should i create another thread and start the timer overthere ? @JeremyFriesner – Hadi Fazelinia Aug 01 '19 at 15:36
  • 4
    No -- what you should do is not try to block inside a while() loop; that doesn't integrate well with Qt's event-driven model. i.e. if you want to stop your receiveTimer "after a while", do that from within the `timeout()` slot rather than trying to do it at the bottom of same function where you started the timer. – Jeremy Friesner Aug 01 '19 at 15:38
  • 3
    Get rid of the while loop. Instead use signals and slots to process data when available. Basically the function needs to be divided up into different slots in your class. – drescherjm Aug 01 '19 at 15:54
  • 2
    You have to wrap your head around the concept of event-based application architecture. You never wait yourself. The framework (Qt from its event loop) will call your code when there is something. You react to it, perhaps set up things to happen later (using a timer, or by sending network request, or by launching external process, or...), and then return as fast as possible, because as long as your code is running, no other code is running. If you find this hard, just think harder :-) And forget threads until you truly grasp the architecture of normal single-threaded Qt app. – hyde Aug 01 '19 at 18:03
  • Given that you have a variable named `sPort` and are waiting on the string `"OK\r\n"` I'm going to hazard a guess and say you're trying to implement a timeout on serial comms? If so you might want to have a look at the [serial port examples](https://doc.qt.io/qt-5/qtserialport-examples.html). That *is* just a guess though. – G.M. Aug 01 '19 at 18:20

1 Answers1

0

You could add this to your loop:

QCoreApplication::processEvents(QEventLoop::AllEvents, 100);

or

QApplication::processEvents(QEventLoop::AllEvents, 100);

My "sleep" function in qt:

void WebView::delay(int sec)
{
    QTime dieTime= QTime::currentTime().addSecs(sec);
    while (QTime::currentTime() < dieTime)
        QCoreApplication::processEvents(QEventLoop::AllEvents, 100);

}

If I anderstand you right, you want than something like that:

QByteArray res;

QTime dieTime= QTime::currentTime().addSecs(sec);
while (!res.contains("OK\r\n") && QTime::currentTime() < dieTime) {
    QCoreApplication::processEvents(QEventLoop::AllEvents, 100);
    qDebug() << res.append(sPort->read(1));
}
Altinsystems
  • 186
  • 2
  • 8
  • Actually i want my while run utmost for 1 sec, then break. First i was doing that with timer and now i recognize that won't work. So, what is best way to do that ? I read QEventloop and QThread, but didn't help to much... – Hadi Fazelinia Aug 04 '19 at 12:24