2010-01-05 58 views
2

我目前正在开发一个应用程序,启动显示其他对话框的单独进程。我试图实现的功能是模拟这些对话框的模态行为。更具体地说,我需要应用程序在启动对话框时停止处理所有输入,鼠标和键盘,并在关闭时恢复。Qt应用程序:模拟模态行为(启用/禁用用户输入)

虽然如果你能够建议如何做到这一点而不求助于Always-On-Top行为,那么这对对话并不是很重要,尽管如此,这也会很好。

要注意,该应用程序是在Windows和Linux下编译的。另外,它不是直接启动对话框的选项。它们在单独的可执行文件中。此外,该应用程序是一个非常复杂的软件,因此单独禁用小部件不是一种选择,或者至少不是一个可行的方法。

我找到了lock()unlock()在Qt 3.3中的QApplication类中的函数。我们目前正在使用Qt 4.5,它似乎没有API。事实上,Qt 4.5 QApplication类似乎并没有提供对Event Loop的访问。

总结:如何在Qt应用程序中禁用/启用用户输入,包括鼠标和键盘快捷键?

回答

4

要全面访问应用程序范围内的事件,请在您的应用程序对象上使用QObject::installEventFilter()QCoreApplication::setEventFilter()
如果你的过滤函数返回true,Qt停止进一步处理事件。

为了不将平台特定的事件转发给其他应用程序,我会选择合适的IPC机制。

+0

谢谢,刚刚发现这一点我自己大约10分钟前。奇迹般有效。顺便说一句, – 2010-01-06 01:02:28

+2

。 _setEventFilter()_不是一个好主意。它似乎永久设置了事件过滤器。 _QObject :: installEventFilter()_和_QObject :: removeEventFilter()_对我更好。参考:http://doc.trolltech.com/4.5/eventsandfilters.html – 2010-01-06 01:07:30

+0

确保你没有全局阻塞事件,如果你这样做,如果你真的想要一些互动仍然工作(如线程之间的信号/插槽,等等)。 – 2010-01-06 17:22:14

1

作为替代答案,您可以创建自己的事件循环,并在必要时开始运行它。您需要创建一个QEventLoop对象,将来自另一个进程的信号连接到其quit()插槽(例如,您正在运行其他程序的QProcess),然后连接exec()循环。如果我正确地阅读了东西,那么当循环运行时,主事件循环将不会处理任何东西。

+0

当然,你必须小心,并确保绘画事件仍然正确处理。否则,如果您尝试移动子对话框,主应用程序看起来像一团糟。虽然有趣的方法。 – 2010-01-07 00:22:06

3

GJ已经提出这个解决办法,但我想我会贴上我的实现仅供参考:

实施,将吸收用户的输入操作的过滤器类。

class BusyAppFilter : public QObject 
{ 
protected: 
    bool eventFilter(QObject *obj, QEvent *event); 
}; 


bool BusyAppFilter::eventFilter(QObject *obj, QEvent *event) 
{ 
    switch (event->type()) 
    { 
    case QEvent::KeyPress: 
    case QEvent::KeyRelease: 
    case QEvent::MouseButtonPress: 
    case QEvent::MouseButtonDblClick: 
    case QEvent::MouseMove: 
    case QEvent::HoverEnter: 
    case QEvent::HoverLeave: 
    case QEvent::HoverMove: 
    case QEvent::DragEnter: 
    case QEvent::DragLeave: 
    case QEvent::DragMove: 
    case QEvent::Drop: 
     return true; 
    default: 
     return QObject::eventFilter(obj, event); 
    } 
} 

然后把这个代码您的QApplication类:

QCursor busyCursor(Qt::WaitCursor); 
setOverrideCursor(busyCursor); 

BusyAppFilter filter; 
installEventFilter(&filter) ; 

//... do the process stuff ... 

removeEventFilter(&filter); 

restoreOverrideCursor(); 
+1

你应该使用'return false'而不是'return QObject :: eventFilter(obj,event);'。所有其他事件过滤器将自动调用。 – 2013-06-06 10:30:34