首页 文章

为QML组件分配键盘快捷键

提问于
浏览
10

我正在使用QML和Qt Creator构建桌面应用程序,我目前正在研究键盘处理以及它如何与QML元素一起工作 . 我已经意识到桌面小部件缺少适当的QML替换 .

我目前的问题是,我希望为一些特定的QML组件分配一些全局键盘快捷键(比如为GUI上的按钮分配键盘快捷键),这些快捷键应该激活它们 . 我能管理的最好的是使用FocusScopes和Key Navigation能够通过键盘导航GUI,但这不是一回事 .

任何人都可以建议在这种情况下做什么? Qt 5有没有这样的功能?我在互联网上找不到任何相关信息 .

4 回答

  • 9

    回答我自己的问题,现在可以在Qt 5.1.1中实现快捷方式 . 使用QML Action 项可以轻松地将快捷键绑定到 ButtonToolButtonsMenuItemQtQuick 控件 . 例如:

    ApplicationWindow {
        ...
        ToolButton { action: openAction } // Add a tool button in a ToolBar
        ...
        Action {
            id: openAction
            text: "&Open"
            shortcut: "Ctrl+O"
            onTriggered: // Do some action
            tooltip: "Open an image"
        }
    }
    

    按Ctrl O将执行onTriggered部分中指定的操作 .

    参考Qt Quick Controls Gallery example

  • 4

    您可以在C(Qt)中使用EventFilter在QML中完全使用快捷方式 .

    您可以通过以下步骤完成:

    1. Create a Shortcut class by C++.
    2. Register QML Type for Shortcut class
    3. Import Shortcut to QML file and handle it.
    
    #ifndef SHORTCUT_H
    #define SHORTCUT_H
    
    #include <QDeclarativeItem>
    
    class Shortcut : public QObject
    {
        Q_OBJECT
        Q_PROPERTY(QVariant key READ key WRITE setKey NOTIFY keyChanged)
    public:
        explicit Shortcut(QObject *parent = 0);
    
        void setKey(QVariant key);
        QVariant key() { return m_keySequence; }
    
        bool eventFilter(QObject *obj, QEvent *e);
    
    signals:
        void keyChanged();
        void activated();
        void pressedAndHold();
    
    public slots:
    
    private:
        QKeySequence m_keySequence;
        bool m_keypressAlreadySend;
    };
    
    #endif // SHORTCUT_H
    
    #include "shortcut.h"
    #include <QKeyEvent>
    #include <QCoreApplication>
    #include <QDebug>
    #include <QLineEdit>
    #include <QGraphicsScene>
    
    Shortcut::Shortcut(QObject *parent)
        : QObject(parent)
        , m_keySequence()
        , m_keypressAlreadySend(false)
    {
        qApp->installEventFilter(this);
    }
    
    void Shortcut::setKey(QVariant key)
    {
        QKeySequence newKey = key.value<QKeySequence>();
        if(m_keySequence != newKey) {
            m_keySequence = key.value<QKeySequence>();
            emit keyChanged();
        }
    }
    
    bool Shortcut::eventFilter(QObject *obj, QEvent *e)
    {
        if(e->type() == QEvent::KeyPress && !m_keySequence.isEmpty()) {
    //If you want some Key event was not filtered, add conditions to here
            if ((dynamic_cast<QGraphicsScene*>(obj)) || (obj->objectName() == "blockShortcut") || (dynamic_cast<QLineEdit*>(obj)) ){
                return QObject::eventFilter(obj, e);
            }
            QKeyEvent *keyEvent = static_cast<QKeyEvent*>(e);
    
            // Just mod keys is not enough for a shortcut, block them just by returning.
            if (keyEvent->key() >= Qt::Key_Shift && keyEvent->key() <= Qt::Key_Alt) {
                return QObject::eventFilter(obj, e);
            }
    
            int keyInt = keyEvent->modifiers() + keyEvent->key();
    
            if(!m_keypressAlreadySend && QKeySequence(keyInt) == m_keySequence) {
                m_keypressAlreadySend = true;
                emit activated();
            }
        }
        else if(e->type() == QEvent::KeyRelease) {
            m_keypressAlreadySend = false;
        }
        return QObject::eventFilter(obj, e);
    }
    
    qmlRegisterType<Shortcut>("Project", 0, 1, "Shortcut");
    
    import Project 0.1
    
    Rectangle {
    .................
    .................
    Shortcut {
            key: "Ctrl+C"
            onActivated: {
                container.clicked()
                console.log("JS: " + key + " pressed.")
            }
        }
    
    }
    
  • 0

    所以假设你在这个按钮上调用一个函数点击这样的事件,

    Button {
      ...
      MouseArea {
        anchor.fill: parent
        onClicked: callThisFunction();
      }
    }
    

    然后,您可以通过这种方式指定分配全局键盘快捷键 . 但是限制是全局QML元素(包含所有其他QML元素的父元素)应该具有焦点 . 防爆 . :

    Rectangle {
      id: parentWindow
      ...
      ...
      Button {
        ...
        MouseArea {
          anchor.fill: parent
          onClicked: callThisFunction();
        }
      }
      Keys.onSelectPressed: callThisFunction()
    }
    

    这不是你想要的,但它可能会有所帮助 .

  • 0

    从Qt 5.9开始,所需的行为甚至是included

    import QtQuick 2.9
    
    Item {
        Shortcut {
           context: Qt.ApplicationShortcut
           sequences: [StandardKey.Close, "Ctrl+W"]
    
            onActivated: {
                container.clicked()
                console.log("JS: Shortcut activated.")
            }
        }
    }
    

    如果省略上下文,它将仅适用于当前活动的窗口,否则对于整个应用程序,请参阅documentation .

相关问题