15

私は QML と Qt Creator を使用したデスクトップ アプリケーションの構築に深く取り組んでおり、現在、キーボード処理と QML 要素との連携方法を研究しています。デスクトップ ウィジェットの適切な QML 代替品がないことは既に認識しています。

私の現在の問題は、いくつかのグローバルキーボードショートカットを特定の QML コンポーネント (GUI のボタンにキーボードショートカットを割り当てるなど) に割り当てて、それらをアクティブにする必要があることです。私が管理できる最善の方法は、FocusScopes と Key Navigation を使用して、キーボードを介して GUI をナビゲートできるようにすることですが、これは同じことではありません。

このシナリオで何をすべきかを誰かが提案できますか? Qt 5 にそのような機能はありますか? インターネット上でこれに関する情報を見つけることができませんでした。

4

4 に答える 4

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.")
        }
    }

}

于 2015-03-23T02:10:28.607 に答える
0

したがって、このようなボタンクリックイベントで関数を呼び出すと仮定すると、

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

次に、この方法でグローバル キーボード ショートカットを割り当てることができます。ただし、グローバル QML 要素 (他のすべての QML 要素を保持する親要素) がフォーカスを持つ必要があるという制限があります。元。:

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

これはまさにあなたが望むものではありませんが、役立つかもしれません。

于 2012-09-11T09:53:20.587 に答える