首页 > 解决方案 > Qt - 禁用/启用所有快捷方式

问题描述

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

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

我已经尝试在我的主窗口上安装一个事件过滤器,但是快捷方式仍然被激活(尽管甚至为每种事件类型返回 true)。

标签: qteventsinputkeyboard-shortcutsdisabled-input

解决方案


我最终为我的 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);
            }
    };

推荐阅读