Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to check if an event loop has pending events outside of a thread?

Calling QCoreApplication::hasPendingEvents() or QAbstractEventDispatcher::instance()->hasPendingEvents() inside of a thread works just fine. However, outside of it, the latter one (with appropriate parameter) always returns false (former cannot be used outside, because it refers to the thread from which it is called).

Here is a complete code:

#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"

Here is the output:

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

Why doesn't QAbstractEventDispatcher.hasPendingEvents() work outside of a thread? Maybe there is an alternative?

like image 345
AlexP Avatar asked Jan 31 '14 03:01

AlexP


1 Answers

What you're showing might be a Qt bug. Alas, you might not need to checking this way if another thread has any pending events.

The only reason I see that you might want to do this is to manage your own thread pool and move objects to threads that are not "busy". You'd keep a list of "busy" and "available" threads. That's what QAbstractEventDispatcher::aboutToBlock signal is for. Your thread pool should connect to this signal for every thread it creates, and add the thread to the "available" list upon reception.

If, on the other hand, you're trying to use it to implement some event compression, that's really the most awkward way to go about it. In another answer, I show how to implement custom event compression, and also how to compress signal-slot calls.

like image 64
Kuba hasn't forgotten Monica Avatar answered Sep 22 '22 00:09

Kuba hasn't forgotten Monica