Qt:等待具有超时管理的信号

Qt: waiting for a signal with timeout management

本文关键字:管理 信号 超时 等待 Qt      更新时间:2023-10-16

我正在寻找一种简单的方法来等待对象发出信号,并使用Qt进行超时管理。

使用Qt类有没有一种简单的方法可以做到这一点?

以下是一个应用示例:

QLowEnergyController controller(remoteDevice);
controller.connectToDevice();
// now wait for controller to emit connected() with a 1sec timeout

基于这篇文章,这里有一个类(封装@EnOpenUK解决方案),并提出了一个具有超时管理的等待功能。

头文件:

#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;
};

实现文件:

#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();
}

示例:

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;

注意,将timeout参数设置为0会使对象永远等待。。。可能是有用的。

在Qt 5中,QtTest标头具有QSignalSpy::wait,用于等待信号发出或超时(以毫秒为单位)。

auto controller = QLowEnergyController{remoteDevice};
auto spy = QSignalSpy{*controller, SIGNAL(connected())};
controller.connectToDevice();
spy.wait(1000);