Reputation: 21514
I'm looking for a simple way to wait for an object to emit signal with timeout management using Qt.
Is there an easy way to do that using Qt classes?
Here is an example of application:
QLowEnergyController controller(remoteDevice);
controller.connectToDevice();
// now wait for controller to emit connected() with a 1sec timeout
Upvotes: 1
Views: 3507
Reputation: 1110
In Qt 5, the QtTest
header has QSignalSpy::wait, to wait until a signal is emitted or a timeout (in milliseconds) occurs.
auto controller = QLowEnergyController{remoteDevice};
auto spy = QSignalSpy{*controller, SIGNAL(connected())};
controller.connectToDevice();
spy.wait(1000);
Upvotes: 2
Reputation: 21514
Based on this post, here is a class (encapsulating @EnOpenUK solution) and proposing a wait function with timeout management.
Header file:
#include <QEventLoop>
class WaitForSignalHelper : public QObject
{
Q_OBJECT
public:
WaitForSignalHelper( QObject& object, const char* signal );
// return false if signal wait timed-out
bool wait();
public slots:
void timeout( int timeoutMs );
private:
bool m_bTimeout;
QEventLoop m_eventLoop;
};
Implementation file:
#include <QTimer>
WaitForSignalHelper::WaitForSignalHelper( QObject& object, const char* signal ) :
m_bTimeout( false )
{
connect(&object, signal, &m_eventLoop, SLOT(quit()));
}
bool WaitForSignalHelper::wait( int timeoutMs )
{
QTimer timeoutHelper;
if ( timeoutMs != 0 ) // manage timeout
{
timeoutHelper.setInterval( timeoutMs );
timeoutHelper.start();
connect(&timeoutHelper, SIGNAL(timeout()), this, SLOT(timeout()));
}
// else, wait for ever!
m_bTimeout = false;
m_eventLoop.exec();
return !m_bTimeout;
}
void WaitForSignalHelper::timeout()
{
m_bTimeout = true;
m_eventLoop.quit();
}
Example:
QLowEnergyController controller(remoteDevice);
controller.connectToDevice();
WaitForSignalHelper helper( controller, SIGNAL(connected()) );
if ( helper.wait( 1000 ) )
std::cout << "Signal was received" << std::endl;
else
std::cout << "Signal was not received after 1sec" << std::endl;
Note that setting timeout parameter to 0
makes the object wait for ever...could be useful.
Upvotes: 3