views:

198

answers:

5

Hello,

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 app 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.

Thanks.

Zac

+4  A: 

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
}
Arnold Spence
Thanks, the including windows.h enables the use of Sleep(); This will do for now as I understand I will not be using this code in the final program because it breaks the event driven model but for now this enables me to test the program as is.
Zac
+3  A: 

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.
Kaleb Pederson
How do I include QTestlib? The #include <QTestlib.h> doesn't seem to be able to find it.
Zac
@Kaleb: good point. I didn't catch that he was actually testing :)
Arnold Spence
A: 

We've been using the below class -

class SleepSimulator{
     [QMutex][1]localMutex;
     [QWaitCondition][2] 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.

photo_tom
A: 

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.

San Jacinto
A: 

See this post to make a cross-platform sleep function with Qt only.

http://stackoverflow.com/questions/3831439/qthow-to-give-a-delay-in-loop-execution

Hope this helps.

Live