2013-06-06 226 views
0

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

此外我需要禁止用户输入。我试图让QEventLoopQEventLoop::ExcludeUserInputEvents标志exec的,但因为文件说,它只是延缓了事件处理:

事件不被丢弃;他们将在下一次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的超时值。

回答

2

我想你正在过滤一些有用的事件(例如,可能涉及QEvent::SockAct)。尝试添加一些调试输出,并找出您实际筛选的事件类型。或者,最好指定要阻止的事件的黑名单,而不是要允许的白名单。见this answer。您也可以使用return QObject::eventFilter(object, event);。你应该使用return false。所有其他事件过滤器将自动调用。

然而,这个解决方案对我来说似乎很奇怪,也不合理,因为您可以拨打setEnabled(false)作为顶级小工具来阻止用户输入,然后您可以使用QApplication::processEvents而不带任何标志。

+0

我发布了和你一样的链接:) – fasked

+0

我知道。但是,您将其作为白名单实施,并且在链接的答案中有一个黑名单。并提到事件类型是不同的。 –

+0

我不能只是禁用顶级小部件,因为它不仅仅是小部件,应用程序全局捕获键盘输入。此外,我已经尝试过黑名单实施之前,我不知道如何,但鼠标点击事件仍然处理。在任何情况下,这都是临时解决方案,现在我只想了解为什么'processEvents'不仅仅是有时而不是总是返回。 – fasked

相关问题