【Qt GUIで迷ったらコレ】キーボードショートカットの取得方法:QShortcut::keys()の使い方


QShortcut::keys()は、Qt GUIアプリケーションにおいて、キーボードショートカットに設定されているキーシーケンスを取得するための関数です。この関数は、Qt 6.0以降で導入されました。

機能

QShortcut::keys()は、QList<QKeySequence>型の値を返します。このリストには、そのショートカットをトリガーするすべてのキーシーケンスが含まれています。

QShortcut shortcut(Qt::CTRL + Qt::Key_Q, this);
connect(&shortcut, &QShortcut::activated, this, &MyWidget::close);

QList<QKeySequence> keys = shortcut.keys();
if (keys.contains(Qt::CTRL + Qt::Key_Q)) {
    // Ctrl + Qキーが押された場合の処理
}

この例では、Ctrl + Qキーのショートカットを作成し、close()スロットに接続しています。その後、QShortcut::keys()を使用して、そのショートカットに設定されているキーシーケンスを取得しています。keysリストにCtrl + Qキーが含まれている場合は、そのキーが押されたことを検知し、処理を実行することができます。

  • QShortcut::keys()は、読み取り専用関数です。キーシーケンスを変更するには、QShortcut::setKeys()関数を使用する必要があります。

利点

  • 動的にキーシーケンスを変更する必要がある場合に便利です。
  • キーボードショートカットの設定状況を簡単に確認できます。
  • キーボードショートカットは、他のアプリケーションによって無効化される可能性があります。
  • QShortcut::keys()は、アプリケーションがアクティブな場合にのみ有効です。
  • キーボードショートカットの動作をカスタマイズするには、QShortcut::autoRepeatプロパティやQShortcut::contextプロパティを使用することができます。
  • QShortcut::keys()以外にも、QShortcut::key()関数を使用して、現在のキーシーケンスを取得することもできます。


例1:Ctrl + Qキーでウィジェットを閉じる

この例では、Ctrl + Qキーのショートカットを作成し、ウィジェットを閉じる処理を実行します。

#include <QtWidgets/QApplication>
#include <QtWidgets/QWidget>
#include <QtWidgets/QShortcut>

class MyWidget : public QWidget {
public:
    MyWidget(QWidget *parent = nullptr);

protected:
    void closeEvent(QCloseEvent *event) override;
};

MyWidget::MyWidget(QWidget *parent) : QWidget(parent) {
    // ショートカットを作成
    QShortcut shortcut(Qt::CTRL + Qt::Key_Q, this);
    connect(&shortcut, &QShortcut::activated, this, &MyWidget::close);
}

void MyWidget::closeEvent(QCloseEvent *event) {
    // ウィジェットを閉じる
    if (event->reason() == QCloseEvent::User) {
        // ユーザーによる操作の場合は、確認ダイアログを表示
        if (QMessageBox::question(this, tr("閉じる"), tr("ウィジェットを閉じますか?"), QMessageBox::Yes | QMessageBox::No) == QMessageBox::No) {
            event->ignore();
            return;
        }
    }

    // 実際に閉じる
    event->accept();
}

int main(int argc, char *argv[]) {
    QApplication app(argc, argv);

    MyWidget widget;
    widget.show();

    return app.exec();
}

例2:複数のキーシーケンスを設定する

この例では、Ctrl + QキーとEscキーの両方に同じ処理を実行するショートカットを作成します。

#include <QtWidgets/QApplication>
#include <QtWidgets/QWidget>
#include <QtWidgets/QShortcut>

class MyWidget : public QWidget {
public:
    MyWidget(QWidget *parent = nullptr);

signals:
    void shortcutActivated();
};

MyWidget::MyWidget(QWidget *parent) : QWidget(parent) {
    // ショートカットを作成
    QShortcut shortcut1(Qt::CTRL + Qt::Key_Q, this);
    QShortcut shortcut2(Qt::Key_Escape, this);
    connect(&shortcut1, &QShortcut::activated, this, &MyWidget::shortcutActivated);
    connect(&shortcut2, &QShortcut::activated, this, &MyWidget::shortcutActivated);
}

void MyWidget::shortcutActivated() {
    // 処理を実行
    QMessageBox::information(this, tr("ショートカット"), tr("ショートカットが押されました。"));
}

int main(int argc, char *argv[]) {
    QApplication app(argc, argv);

    MyWidget widget;
    widget.show();

    return app.exec();
}

例3:キーシーケンスを動的に変更する

この例では、ボタンをクリックしたときに、Ctrl + Shift + Aキーのショートカットのキーシーケンスを変更します。

#include <QtWidgets/QApplication>
#include <QtWidgets/QWidget>
#include <QtWidgets/QShortcut>
#include <QtWidgets/QPushButton>

class MyWidget : public QWidget {
public:
    MyWidget(QWidget *parent = nullptr);

private:
    QShortcut *shortcut;
    QPushButton *button;
};

MyWidget::MyWidget(QWidget *parent) : QWidget(parent) {
    // ショートカットを作成
    shortcut = new QShortcut(Qt::CTRL + Qt::Shift + Qt::Key_A, this);

    // ボタンを作成
    button = new QPushButton(tr("キーシーケンスを変更"), this);
    connect(button, &QPushButton::clicked, this, &MyWidget::changeKeySequence);
}

void MyWidget::changeKeySequence() {
    // キーシーケンスを変更
    shortcut->setKeys(Qt::ALT + Qt::Key_F4);
}

int main(int argc, char *argv[]) {
    QApplication app(argc, argv);

    MyWidget widget;
    widget.show();

    return app.exec();
}


以下に、QShortcut::keys()の代替方法として考えられる方法をいくつか紹介します。

QKeySequence::toString()`を使用する

QKeySequence::toString()関数は、キーシーケンスを文字列に変換します。この文字列には、キーシーケンスを構成するすべてのキーがカンマ区切りで含まれています。

QShortcut shortcut(Qt::CTRL + Qt::Key_Q, this);
QString keySequenceString = shortcut.key().toString();

このコードは、Ctrl + Qキーのショートカットのキーシーケンスを文字列に変換し、keySequenceString変数に格納します。

QObject::property()`を使用する

QObject::property()関数は、オブジェクトのプロパティの値を取得します。QShortcutクラスは、keyというプロパティを持っており、このプロパティには現在のキーシーケンスが格納されています。

QShortcut shortcut(Qt::CTRL + Qt::Key_Q, this);
QKeySequence keySequence = shortcut.property("key").value<QKeySequence>();

このコードは、Ctrl + Qキーのショートカットのキーシーケンスを取得し、keySequence変数に格納します。

シグナルとスロットを使用する

QShortcutクラスは、activatedシグナルをemitします。このシグナルは、ショートカットキーが押されたときにemitされます。シグナルハンドラの中で、現在のキーシーケンスを取得することができます。

QShortcut shortcut(Qt::CTRL + Qt::Key_Q, this);
connect(&shortcut, &QShortcut::activated, this, &MyWidget::onShortcutActivated);

void MyWidget::onShortcutActivated() {
    QKeySequence keySequence = shortcut.key();
    // キーシーケンスを使用して処理を実行
}

このコードは、Ctrl + Qキーのショートカットが押されたときに、onShortcutActivated()スロットを呼び出します。このスロットの中で、shortcut.key()を使用して現在のキーシーケンスを取得し、処理を実行することができます。

カスタムクラスを作成する

QShortcutクラスを継承したカスタムクラスを作成し、独自のキーシーケンス取得方法を実装することもできます。

どの方法を選択するべきか

どの方法を選択するかは、状況によって異なります。

  • 複雑なキーシーケンス取得ロジックが必要な場合は、カスタムクラスを作成するのが良いでしょう。
  • キーシーケンスが押されたときに処理を実行する必要がある場合は、シグナルとスロットを使用するのが最も適切です。
  • キーシーケンスをQKeySequenceオブジェクトとして取得したい場合は、QObject::property()を使用するのが良いでしょう。
  • キーシーケンスを単純に文字列として取得したい場合は、QKeySequence::toString()を使用するのが最も簡単です。