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

Ale*_*exP 7 qt multithreading event-loop qthread qt5

调用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"
Run Code Online (Sandbox Code Playgroud)

这是输出:

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
Run Code Online (Sandbox Code Playgroud)

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

Rei*_*ica 3

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

我发现您可能想要这样做的唯一原因是管理您自己的线程池并将对象移动到不“忙”的线程。您将保留“忙碌”和“可用”线程的列表。这就是QAbstractEventDispatcher::aboutToBlock信号的用途。您的线程池应该为其创建的每个线程连接到此信号,并在接收时将线程添加到“可用”列表中。

另一方面,如果您尝试使用它来实现某些事件压缩,那么这确实是最尴尬的方法。在另一个答案中,我展示了如何实现自定义事件压缩,以及如何压缩信号槽调用。