【发布时间】:2016-06-16 06:22:26
【问题描述】:
我问的是在事件引擎中有很多 qt 事件排队的情况。 QTimer 是否会通过事件发出 timeout() 信号,并将 queuedConnection 与插槽一起创建另一个事件?
【问题讨论】:
标签: c++ qt qtimer qapplication
我问的是在事件引擎中有很多 qt 事件排队的情况。 QTimer 是否会通过事件发出 timeout() 信号,并将 queuedConnection 与插槽一起创建另一个事件?
【问题讨论】:
标签: c++ qt qtimer qapplication
当QTimer 发出QTimer::timeout 信号时,与Qt::DirectConnection 连接的槽将立即被调用。如果使用排队连接,它会安排一个事件来调用该槽,该槽将由事件循环处理。 QTimer 使用 timerEvent 到 emit the timeout signal。
【讨论】:
Qt::DirectConnection时,如果程序正在运行函数A并且发出超时信号,那么A的执行是暂停,连接到超时信号的槽被执行,执行完成后,A的执行被恢复?假设A、定时器和连接的槽都属于同一个线程。
Qt::DirectConnection 类型的所有连接都是这种情况吗?我对此有点困惑,因为在我阅读的任何地方,直接连接都被解释为“[插槽]将在发出信号时立即被调用”或“它就像一个函数调用”。实际上,现在我在QTimer 上对此进行了测试,但在这种情况下,直接连接似乎就像排队连接(QTimer 和连接的插槽在我的测试中都位于同一个线程中)。我不明白他们的区别?!
timeout 信号是在timerEvent 事件处理程序中发出的。此事件在QTimer 对象所在的线程中处理。如果正在执行函数A,应用程序将等待它完成,然后再开始处理事件。但是如果你在不同的线程中创建你的定时器并使用Qt::DirectConnection,那么这个槽会立即被执行,不管A是否被执行,它都会在定时器所在的线程中执行。所以小心。
不,默认情况下它不是排队连接,除非它在不同的线程中运行。因此它是 DirectConnection。
我想说,一般来说,如果你想保证事件的顺序,你最好将 Qt::QueuedConnection 与定时器之类的东西一起使用,即使在同一个线程中,这样事件就会进入队列并且是不只是对 immidiatley 采取行动——因为这种行为更像是一种“中断”。
但是,如果您真的希望立即执行计时器 timeout(),那么请使用 Qt::DirectConnection - 我觉得您通常需要更加小心这种连接类型(例如可以在其他正常代码的中间)。
编辑
我所说的“普通代码”是指...嗯,请参阅下面的 cmets:
【讨论】:
For QTimer to work, you must have an event loop in your application; that is, you must call QCoreApplication::exec() somewhere. Timer events will be delivered only while the event loop is running..
QTimer::singleshot(0, object, &Object::slot); 来“排队”调用函数。
Qt::AutoConnection 而言。发出信号会导致QMetaObject::activate call, which checks the specified connection type。如果指定了Qt::AutoConnection,它将检查发送线程和接收线程的线程亲缘关系。如果它们相同,则使用直接连接,如果它们不同,则使用排队连接。
当一个 QTimer 超时时,每个将这个 QTimer 的信号与一个槽连接的 Signal-Slot 连接都会触发这个槽一次。
【讨论】: