如何检查事件循环是否在线程外有待处理事件?

时间:2014-01-31 03:08:12

标签: multithreading qt qt5 qthread event-loop

在线程内部调用QCoreApplication::hasPendingEvents()QAbstractEventDispatcher::instance()->hasPendingEvents()可以正常工作。但是,在它之外,后者(带有适当的参数)总是返回false(前者不能在外面使用,因为它指的是调用它的线程)。

这是一个完整的代码:

#include <QCoreApplication>
#include <QAbstractEventDispatcher>
#include <QThread>
#include <QDebug>

bool hasPendingEvents(QThread *thread = 0) {
  return QAbstractEventDispatcher::instance(thread)->hasPendingEvents();
}

class MyObject: public QObject {
  Q_OBJECT

public slots:
  void Run() {
    qDebug() << __LINE__ << hasPendingEvents() << QCoreApplication::hasPendingEvents();
    QThread::sleep(1);
  }
};

int main(int argc, char *argv[]) {
  QCoreApplication app(argc, argv);

  QThread thread;
  MyObject t;
  t.moveToThread(&thread);
  thread.start();
  for (int i = 0; i<4; ++i) QMetaObject::invokeMethod(&t, "Run", Qt::QueuedConnection);

  for (int i = 0; i<10; ++i) {
    QThread::msleep(500);
    qDebug() << __LINE__ << hasPendingEvents(&thread) << hasPendingEvents(t.thread());
  }
  return 0;
}

#include "main.moc"

这是输出:

15 true true
31 false false
31 false false
15 true true
31 false false
31 false false
15 true true
31 false false
31 false false
15 false false
31 false false
31 false false
31 false false
31 false false

为什么QAbstractEventDispatcher.hasPendingEvents()不在线程之外工作?也许有另一种选择?

1 个答案:

答案 0 :(得分:2)

您展示的内容可能是Qt错误。唉,如果另一个线程有任何挂起事件,你可能不需要这样检查。

我看到您可能想要这样做的唯一原因是管理您自己的线程池并将对象移动到非忙碌的线程#34;。你要保留一份&#34;忙碌&#34;和&#34;可用&#34;线程。这是QAbstractEventDispatcher::aboutToBlock信号的用途。您的线程池应该为它创建的每个线程连接到此信号,并将线程添加到&#34; available&#34;接待时列出。

另一方面,如果您尝试使用它来实现某些事件压缩,那么这真的是最尴尬的方式。 In another answer,我展示了如何实现自定义事件压缩,以及如何压缩信号槽调用。