我目前正在开发一个应用程序,该应用程序启动显示其他对话框的单独进程。我试图实现的功能是模拟这些对话框的模态行为。更具体地说,我需要应用程序在对话框启动时停止处理鼠标和键盘的所有输入,并在关闭时恢复。
对话框保留在应用程序之上并不是那么重要,尽管如果你可以建议如何在不诉诸于Always-On-Top行为的情况下做到这一点,那也很好。
要注意,应用程序是在Windows和Linux下编译的。此外,不能直接启动对话框。它们位于不同的可执行文件中。此外,该应用程序是一个非常复杂的软件,因此单独禁用小部件不是一种选择,或者至少是不可行的。
我在Qt 3.3中的QApplication类中找到了 lock()和 unlock()函数。我们目前正在使用Qt 4.5,它似乎没有那个API。事实上,Qt 4.5 QApplication类似乎也不提供对事件循环的访问。
总结:如何在Qt应用程序中禁用/启用用户输入,包括鼠标和键盘快捷键?
答案 0 :(得分:5)
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 :(得分:4)
要获得对应用范围事件的完全访问权限,请在应用程序对象上使用QObject::installEventFilter()
或QCoreApplication::setEventFilter()
。
如果您的过滤器函数返回true
,Qt将停止进一步处理该事件。
为了不将特定事件转发到其他应用程序,我会选择合适的IPC机制。
答案 2 :(得分:1)
作为替代答案,您可以创建自己的事件循环并在必要时开始运行它。您需要创建一个QEventLoop
对象,将来自另一个进程的信号连接到其quit()
个插槽(例如来自运行其他程序的QProcess
),然后{{ 1}}循环。如果我正确读取了内容,那么当该循环运行时,主事件循环将不会处理任何内容。