Qt应用程序:模拟模态行为(启用/禁用用户输入)

时间:2010-01-05 22:27:00

标签: c++ qt qt4

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

对话框保留在应用程序之上并不是那么重要,尽管如果你可以建议如何在不诉诸于Always-On-Top行为的情况下做到这一点,那也很好。

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

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

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

3 个答案:

答案 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}}循环。如果我正确读取了内容,那么当该循环运行时,主事件循环将不会处理任何内容。