Qt5:如何等待线程中的信号(带滤波器)?

Qt5: How to wait for a signal (with filter) in a thread?

提问人:Eric Qiang 提问时间:10/28/2023 最后编辑:Eric Qiang 更新时间:10/29/2023 访问量:56

问:

我已经阅读了帖子如何等待线程中的信号,但仍然有一些困惑:

如果我想等待带有参数的信号,并根据某些特定条件过滤传入信号,该怎么办?
假设我们有
signal: triggered(int i)

QTimer timer;
timer.setSingleShot(true);
QEventLoop loop;
connect( this, &MyClass::triggered, &loop, [&](int i) {
    // only 123 would stop the event loop, otherwise keep waiting until timeout
    if (i == 123)  
        loop.quit();
} );
connect( &timer, &QTimer::timeout, &loop, &QEventLoop::quit );
timer.start(msTimeout);
loop.exec();

if(timer.isActive())
    qDebug("Got 123! It may not be carried by the first incoming signal.");
else
    qDebug("timeout");

问题:

  • 对于第一个连接到 lambda 的参数,第三个参数是否必要?connect&loop
  • 首先,我应该在某个地方吗?connectdisconnect
  • 我看到一些评论提到内在应该非常小心地使用,为什么?我是否以正确的方式这样做?QEventLoop
  • 班级能做到这一点吗?QSignalSpy
  • 是否可以将其重写为可重用的标题模板?例如:waitForTimeout(QObject* sender, Func1 signal, Func2 predicate, int msec)
C++ 多线程 Qt 等待 信号-插槽

评论

2赞 Igor Tandetnik 10/28/2023
“第三个论点有必要吗?”是的,这是谨慎的。这个参数是一个 ;其目的是让Qt在删除此对象时自动断开信号(假设lambda以某种方式与该对象相关)。在您的示例中,假设发生超时,循环退出,并且由于它是堆栈上的局部变量,因此对象被销毁。如果您没有为第一个信号指定参数,则该信号仍将保持连接状态,而 lambda 将保持悬空引用。如果信号真的稍后触发,砰!&loopQObject*loop&loopconnect
1赞 Igor Tandetnik 10/28/2023
“第一次连接时,我应该在某个地方断开它吗?”如果确实传递了参数,则信号将在超出范围时自动断开连接。如果你不这样做,那么是的,你可能应该这样做,或者就像我说的那样,信号会触发并尝试访问悬空的参考。但是,如果没有参数,您甚至无法断开此特定连接,因为无法识别它。你必须断开与这个信号的所有连接,如果其他人也在听它,这当然可能会破坏一切。&looploop&loop
0赞 Igor Tandetnik 10/28/2023
QSignalSpy用于测试。我不确定它应该如何帮助这里。我什至不确定“实现此”中的“此”是什么。还有什么问题有待解决?
0赞 Eric Qiang 10/29/2023
@IgorTandetnik 感谢您对第一个 .对于您的最后一条评论,有一个函数 wait,可用于信号等待。“this”用于整个实现,删除上面的所有现有代码,并用&loopconnectQSignalSpy.wait

答: 暂无答案