Qt - 禁用/启用所有快捷方式

时间:2018-06-16 11:13:38

标签: qt events input keyboard-shortcuts disabled-input

我有一个带有3D视口的Qt 5应用程序,用户可以在持有RClick并使用WASDQE时导航。我想这样按住Ctrl会减慢相机移动速度,但这样做会激活快捷方式。

是否可以禁用和启用所有快捷方式,以便在鼠标按钮关闭时禁用它们?

我尝试在我的主窗口上安装一个事件过滤器,但仍然会激活快捷方式(尽管每个事件类型都返回true)。

1 个答案:

答案 0 :(得分:0)

我最终为我的3D视口小部件创建了一个事件过滤器来检查鼠标按下。每次我遇到这些事件(以及密钥释放事件),然后我在主窗口上调用一个函数(checkShortcutsEnabled())来切换快捷方式内容,具体取决于是否没有按下按钮。

我还检查键释放事件的原因是只在没有按下键盘修改器时重新启用快捷键(这样如果你在键盘键之前释放鼠标按键,你就不会意外地跳过快捷键)

快捷方式默认为Qt::WindowShortcut,这意味着它们可以在窗口的任何位置激活。当鼠标按钮在视口上方向下时,我暂时将其切换到Qt::WidgetShortcut,这意味着如果窗口小部件收到快捷方式(但不是视口窗口小部件,它是我的主窗口的子窗口),它们可以被激活。它是禁用/重新启用它们的更好选择,因为我不必修改保存禁用状态,以及工具栏按钮变灰。

主窗口类

    class StageEditorWindow : public QMainWindow {
        Q_OBJECT

        friend class ViewportEventFilter;

        protected:
            /**
             * @brief Checks if any mouse buttons are down and disables/enables shortcuts appropriately
             */
            void checkShortcutsEnabled() {
                QList<QAction*> actions = findChildren<QAction*>();

                if (QApplication::mouseButtons() != Qt::NoButton) {
                    for (QAction *a : actions) a->setShortcutContext(Qt::WidgetShortcut);
                } else if (QApplication::keyboardModifiers() == Qt::NoModifier) {
                    //Don't re-enable shortcuts until modifers have been released
                    for (QAction *a : actions) a->setShortcutContext(Qt::WindowShortcut);
                }
            }

        //Don't forget to install the event filter in your constructor

    };

事件过滤器类

    /**
     * @brief Used to check if the mouse is pressed over the viewport and disable shortcuts if so
     */
    class ViewportEventFilter : public QObject {
        Q_OBJECT

        private:
            StageEditorWindow *w;

        public:
            ViewportEventFilter(StageEditorWindow *w, QObject *parent = nullptr) :
                QObject(parent),
                w(w) {}

        protected:
            bool eventFilter(QObject *watched, QEvent *event) {
                if (event->type() == QEvent::MouseButtonPress ||
                        event->type() == QEvent::MouseButtonRelease ||
                        event->type() == QEvent::KeyRelease) {
                    w->checkShortcutsEnabled();
                }

                return QObject::eventFilter(watched, event);
            }
    };