2013-06-06 5 views
0

В моем приложении мне нужно дождаться завершения внешней программы (с использованием QProcess). Я хочу, чтобы приложение было ответственным, поэтому методы блокировки неприемлемы.QApplication :: processEvents никогда не возвращает

Также мне нужно запретить ввод пользователя. Я пытался сделать QEventLoop и EXEC его с 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.

ответ

2

Я думаю, вы фильтруете некоторые полезные события (например, может быть задействован QEvent::SockAct). Попробуйте добавить отладочный вывод и выяснить, какие типы событий вы фактически фильтруете. Или, может быть, лучше указать черный список событий, которые вы хотите заблокировать, вместо белого списка событий, которые вы хотите разрешить. См. this answer.

Также вы не должны использовать return QObject::eventFilter(object, event);. Вы должны использовать return false. Все остальные фильтры событий будут вызываться автоматически.

Это решение, однако, кажется странным и необоснованным для меня, потому что вы можете просто позвонить setEnabled(false) для своего виджета верхнего уровня, чтобы заблокировать ввод пользователя, а затем вы можете использовать QApplication::processEvents без каких-либо флагов.

+0

Я разместил ту же ссылку, что и вы :) – fasked

+0

Я знаю. Но вы реализуете это как белый список, а в связанном ответе есть черный список. И упомянутые типы событий различны. –

+0

Я не могу просто отключить виджеты верхнего уровня, потому что речь идет не только о виджетах, но и во всем мире приложение захватывает клавиатуру. Кроме того, я пробовал до реализации черного списка, и я не знаю, как все события щелчка мыши все еще обрабатываются. В любом случае это временное решение, и теперь я просто хочу понять, почему 'processEvents' не возвращается только иногда, а не всегда. – fasked

Смежные вопросы