How do I create a pause/wait function using Qt?

C++QtSleepWait

C++ Problem Overview


I'm playing around with Qt, and I want to create a simple pause between two commands. However it won't seem to let me use Sleep(int mili);, and I can't find any obvious wait functions.

I am basically just making a console application to test some class code which will later be included in a proper Qt GUI, so for now I'm not bothered about breaking the whole event-driven model.

C++ Solutions


Solution 1 - C++

I wrote a super simple delay function for an application I developed in Qt.

I would advise you to use this code rather than the sleep function as it won't let your GUI freeze.

Here is the code:

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

To delay an event by n seconds - use addSecs(n).

Solution 2 - C++

From Qt5 onwards we can also use

Static Public Members of QThread

void 	msleep(unsigned long msecs)
void 	sleep(unsigned long secs)
void 	usleep(unsigned long usecs)

Solution 3 - C++

This previous question mentions using qSleep() which is in the QtTest module. To avoid the overhead linking in the QtTest module, looking at the source for that function you could just make your own copy and call it. It uses defines to call either Windows Sleep() or Linux nanosleep().

#ifdef Q_OS_WIN
#include <windows.h> // for Sleep
#endif
void QTest::qSleep(int ms)
{
    QTEST_ASSERT(ms > 0);

#ifdef Q_OS_WIN
    Sleep(uint(ms));
#else
    struct timespec ts = { ms / 1000, (ms % 1000) * 1000 * 1000 };
    nanosleep(&ts, NULL);
#endif
}

Solution 4 - C++

Small +1 to kshark27's answer to make it dynamic:

#include <QTime>

void delay( int millisecondsToWait )
{
    QTime dieTime = QTime::currentTime().addMSecs( millisecondsToWait );
    while( QTime::currentTime() < dieTime )
    {
        QCoreApplication::processEvents( QEventLoop::AllEvents, 100 );
    }
}

Solution 5 - C++

I've had a lot of trouble over the years trying to get QApplication::processEvents to work, as is used in some of the top answers. IIRC, if multiple locations end up calling it, it can end up causing some signals to not get processed (https://doc.qt.io/archives/qq/qq27-responsive-guis.html). My usual preferred option is to utilize a QEventLoop (https://doc.qt.io/archives/qq/qq27-responsive-guis.html#waitinginalocaleventloop).

inline void delay(int millisecondsWait)
{
    QEventLoop loop;
    QTimer t;
    t.connect(&t, &QTimer::timeout, &loop, &QEventLoop::quit);
    t.start(millisecondsWait);
    loop.exec();
}

Solution 6 - C++

We've been using the below class -

class SleepSimulator{
	 QMutex localMutex;
	 QWaitCondition sleepSimulator;
public:
	SleepSimulator::SleepSimulator()
	{
		localMutex.lock();
	}
	void sleep(unsigned long sleepMS)
	{
		sleepSimulator.wait(&localMutex, sleepMS);
	}
	void CancelSleep()
	{
		sleepSimulator.wakeAll();
	}
};

QWaitCondition is designed to coordinate mutex waiting between different threads. But what makes this work is the wait method has a timeout on it. When called this way, it functions exactly like a sleep function, but it uses Qt's event loop for the timing. So, no other events or the UI are blocked like normal windows sleep function does.

As a bonus, we added the CancelSleep function to allows another part of the program to cancel the "sleep" function.

What we liked about this is that it lightweight, reusable and is completely self contained.

QMutex: http://doc.qt.io/archives/4.6/qmutex.html

QWaitCondition: http://doc.qt.io/archives/4.6/qwaitcondition.html

Solution 7 - C++

To use the standard sleep function add the following in your .cpp file:

#include <unistd.h>

As of Qt version 4.8, the following sleep functions are available:

void QThread::msleep(unsigned long msecs)
void QThread::sleep(unsigned long secs)
void QThread::usleep(unsigned long usecs)

To use them, simply add the following in your .cpp file:

#include <QThread>

Reference: QThread (via Qt documentation): http://doc.qt.io/qt-4.8/qthread.html

Otherwise, perform these steps...

Modify the project file as follows:

CONFIG += qtestlib

Note that in newer versions of Qt you will get the following error:

Project WARNING: CONFIG+=qtestlib is deprecated. Use QT+=testlib instead.

... so, instead modify the project file as follows:

QT += testlib

Then, in your .cpp file, be sure to add the following:

#include <QtTest>

And then use one of the sleep functions like so:

usleep(100);

Solution 8 - C++

Since you're trying to "test some class code," I'd really recommend learning to use QTestLib. It provides a QTest namespace and a QtTest module that contain a number of useful functions and objects, including QSignalSpy that you can use to verify that certain signals are emitted.

Since you will eventually be integrating with a full GUI, using QTestLib and testing without sleeping or waiting will give you a more accurate test -- one that better represents the true usage patterns. But, should you choose not to go that route, you could use QTestLib::qSleep to do what you've requested.

Since you just need a pause between starting your pump and shutting it down, you could easily use a single shot timer:

class PumpTest: public QObject {
    Q_OBJECT
    Pump &pump;
public:
    PumpTest(Pump &pump):pump(pump) {};
public slots:
    void start() { pump.startpump(); }
    void stop() { pump.stoppump(); }
    void stopAndShutdown() {
        stop();
        QCoreApplication::exit(0);
    }
    void test() {
        start();
        QTimer::singleShot(1000, this, SLOT(stopAndShutdown));
    }
};

int main(int argc, char* argv[]) {
    QCoreApplication app(argc, argv);
    Pump p;
    PumpTest t(p);
    t.test();
    return app.exec();
}

But qSleep() would definitely be easier if all you're interested in is verifying a couple of things on the command line.

EDIT: Based on the comment, here's the required usage patterns.

First, you need to edit your .pro file to include qtestlib:

CONFIG += qtestlib

Second, you need to include the necessary files:

  • For the QTest namespace (which includes qSleep): #include <QTest>

  • For all the items in the QtTest module: #include <QtTest>. This is functionally equivalent to adding an include for each item that exists within the namespace.

Solution 9 - C++

@kshark27's answer didn't work for me for some reason (because I use Qt 5.7?) so I ended up doing this:

while (someCondition) {

   // do something

   QApplication::processEvents();
   QThread::sleep(1); // 1 second

};

If this is done in the GUI thread, it obviously introduces a 1 second GUI lag before responding to user events. But if you can live with it, this solution is probably an easiest to implement and even Qt endorses it in their Threading Basics article (see When to Use Alternatives to Threads section).

Solution 10 - C++

we can use following method QT_Delay:

QTimer::singleShot(2000,this,SLOT(print_lcd()));

This will wait for 2 seconds before calling print_lcd().

Solution 11 - C++

Similar to some answers here, but maybe a little more lightweight

void MyClass::sleepFor(qint64 milliseconds){
    qint64 timeToExitFunction = QDateTime::currentMSecsSinceEpoch()+milliseconds;
    while(timeToExitFunction>QDateTime::currentMSecsSinceEpoch()){
        QApplication::processEvents(QEventLoop::AllEvents, 100);
    }
}

Solution 12 - C++

If you want a cross-platform method of doing this, the general pattern is to derive from QThread and create a function (static, if you'd like) in your derived class that will call one of the sleep functions in QThread.

Solution 13 - C++

This work fine with Qt5:

void wait( int ms ) {
   QElapsedTimer timer;
   timer.start();

   while ( timer.elapsed() < ms )
       QCoreApplication::processEvents();
}

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionZacView Question on Stackoverflow
Solution 1 - C++Kartik SharmaView Answer on Stackoverflow
Solution 2 - C++YashView Answer on Stackoverflow
Solution 3 - C++Arnold SpenceView Answer on Stackoverflow
Solution 4 - C++GraehamFView Answer on Stackoverflow
Solution 5 - C++dvntehn00bzView Answer on Stackoverflow
Solution 6 - C++photo_tomView Answer on Stackoverflow
Solution 7 - C++Richard NalezynskiView Answer on Stackoverflow
Solution 8 - C++Kaleb PedersonView Answer on Stackoverflow
Solution 9 - C++NeurotransmitterView Answer on Stackoverflow
Solution 10 - C++user11514364View Answer on Stackoverflow
Solution 11 - C++hytromoView Answer on Stackoverflow
Solution 12 - C++San JacintoView Answer on Stackoverflow
Solution 13 - C++CalanorView Answer on Stackoverflow