在我的应用程序中,我需要等到外部程序(使用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
的超时值。
答案 0 :(得分:2)
我猜你正在过滤一些有用的事件(例如,可能涉及QEvent::SockAct
)。尝试添加一些调试输出,找出实际过滤的事件类型。或者,最好指定要阻止的事件的黑名单,而不是要允许的白名单事件。请参阅this answer。
此外,您不应使用return QObject::eventFilter(object, event);
。您应该使用return false
。将自动调用所有其他事件过滤器。
然而,这个解决方案对我来说似乎很奇怪和不合理,因为你只需要为你的顶级小部件调用setEnabled(false)
来阻止用户输入,然后就可以使用QApplication::processEvents
而不用任何标记。