QApplication :: processEvents永远不会返回

时间:2013-06-06 09:57:38

标签: event-handling qt4

在我的应用程序中,我需要等到外部程序(使用QProcess)完成。我想让应用程序负责,因此阻止方法是不可接受的。

另外我需要禁止用户输入。我试图制作QEventLoop并用QEventLoop::ExcludeUserInputEvents标志执行它,但正如文档所说它只会延迟事件处理:

  

事件不会被丢弃;它们将在下次没有processEvents()标志的情况下调用ExcludeUserInputEvents时发送。

所以我实现了简单的事件过滤器并将其安装在qApp上(这个想法来自Qt Application: Simulating modal behaviour (enable/disable user input))。它运行良好,但有时QApplication::processEvents函数永远不会返回,即使我指定了最大超时。任何人都可以帮助我理解定期发生的原因

class UserInputEater : public QObject
{
public:
    bool eventFilter(QObject *object, QEvent *event)
    {
        switch(event->type())
        {
        case QEvent::UpdateRequest:
        case QEvent::UpdateLater:
        case QEvent::Paint:
            return QObject::eventFilter(object, event);
        default:
            return true;
        }
    }
};

-

UserInputEater eventEater;
qApp->installEventFilter(&eventEater);

QProcess prc;
prc.start("...");
while(!prc.waitForFinished(10))
{
    if(qApp->hasPendingEvents())
    {
        // Sometimes it never returns from processEvents
        qApp->processEvents(QEventLoop::AllEvents, 100); 
    }
}

qApp->removeEventFilter(&eventEater);

UPD:似乎取决于QProcess::waitForFinished的超时值。

1 个答案:

答案 0 :(得分:2)

我猜你正在过滤一些有用的事件(例如,可能涉及QEvent::SockAct)。尝试添加一些调试输出,找出实际过滤的事件类型。或者,最好指定要阻止的事件的黑名单,而不是要允许的白名单事件。请参阅this answer

此外,您不应使用return QObject::eventFilter(object, event);。您应该使用return false。将自动调用所有其他事件过滤器。

然而,这个解决方案对我来说似乎很奇怪和不合理,因为你只需要为你的顶级小部件调用setEnabled(false)来阻止用户输入,然后就可以使用QApplication::processEvents而不用任何标记。