QT:如何确定事件处理器是否正忙

时间:2014-08-06 14:31:30

标签: c++ qt

在我目前的Qt应用程序中,我试图使用

关闭它
QCoreApplication::quit();

现在关闭应用程序需要一分多钟的时间。我相信这是因为主表单的事件处理器很忙。我的问题是:我有办法确定导致这种情况的原因。以下是我怀疑的事情

1个排队连接。 我有很多排队的连接。也许其中一些连接没有得到处理

2-Event Loop。 可能是事件循环忙于做一些我不知道的事情(期待)

有关我可以采取哪些措施来检查应用程序需要如此长时间关闭的建议?

更新

我尝试QCoreApplication::hasPendingEvents()并返回true

1 个答案:

答案 0 :(得分:1)

没有排队的连接被“处理”,或者事件循环“忙”。一个事件循环本质上就是这个(在C ++伪代码中):

forever {
  while (! nativeEventQueue.isEmpty()) {
    QueueEntry entry = nativeEventQueue.take_first().convert();
    QCoreApplication::sendEvent(entry.object, entry.event);
    delete entry.event;
  }
  while (! eventQueue.isEmpty()) {
    QueueEntry entry(eventQueue.take_first());
    QCoreApplication::sendEvent(entry.object, entry.event);
    delete entry.event;
  }
  waitFor(eventQueue, nativeEvents);
}

所有事件处理都是通过发送部分QEventQObject来完成的。这就是事件循环所做的一切。某些事件会导致信号被发射。这不是事件循环繁忙,而是在QObject::event和重写的实现中运行的代码!这段代码阻塞事件循环,因为当它运行时,事件循环的代码在同一个线程中并且在调用堆栈上 - 它无法运行。

在Qt小部件和其他对象中连接到信号的插槽中的代码实际执行时QCoreApplication::sendEventQCoreApplication::notify在调用堆栈上,事件循环(QAbstractEventDispatcher)在某处更深入的调用堆栈,最后是QEventLoop

如果您的代码执行速度比添加到队列中的事件慢,那么您将遇到问题。

这个简单的例子演示了这样的代码。在实际程序中,它当然会“混淆”,但问题通常会减少到:

void Class::customEvent(QEvent * ev) {
  ...
  QCoreApplication::postEvent(this, new EventFoo(...));
  ...
  QCoreApplication::postEvent(this, new EventFoo(...));
  ...
}

显式事件发布可以用非常不同的方式表达。例如,它可能是您向自己发送信号:

void Class::mySlot() {
  ...
  emit signal1();
  ...
  emit signal2();
}

如果signal1signal2都通过排队连接连接到mySlot,则应用程序将耗尽内存,因为事件队列只会增长,永不缩小。它可能仍然显示出响应。