Qtでグローバルホットキーを利用する


これは私が全部作ったものではなく、他人様の作られた成果をすこし手直しして、私がアプリケーションの形に仕上げたものです。

通常、キーボードを操作すると、アクティブ(最前面)にあるウィンドウにキー押下イベントが送られます。別のアプリがアクティブになっているときで、あらかじめ決めておいたキーが押されたときに自分のアプリでそのキー操作を横取りして、特別な処理を実行したいことがあります。通常は非アクティブ状態で待機しておき、Ctrl+Alt+◯を押すとスクリーンショットを撮るみたいなやつです。Windows Vista以降ならRegisterHotKeyというAPIがあって、そういったことを実現できます。もっと古いWindowsならSetWindowsHookExというAPIを使ってキーボードイベントをフックするという方法もありますが、今は昔のテクニックとなっています。Windowsはそのどちらかで良いとして、やはりマルチプラットフォーム対応にしたいです。macOSとLinuxでも同じようなことを実現したいと思ったら、ありました。

リンク先がこれです。
https://stackoverflow.com/questions/35564502/c-qt-global-hotkeys

UGlobalHotkeyというライブラリを使うと実現できそうです。ライセンスはパブリックドメインとのことです。
https://github.com/falceeffect/UGlobalHotkey

では早速このリポジトリをフォークして改造してみます。
https://github.com/soramimi/UGlobalHotkey

Qt Creatorからプロジェクトファイルを開きます。uglobalhotkey.proというのがライブラリで、こちらを先にビルドします。ExampleApp.proはサンプルアプリケーションです。

ExampleAppを実行すると下図の様なウィンドウが表示されます。

このアプリケーションがアクティブかどうかにかかわらず、Ctrl+Shift+F12を押すと、ラベルの数字が増加するようになっています。

ライブラリの使い方はとても簡単で、MainWindow.cppのコンストラクタなどで、下記のようなコードを記述するだけです。

    QString hotkey = "Ctrl+Shift+F12";
    ui->label->setText(QString("Press %1 key.").arg(hotkey));

    UGlobalHotkeys *hotkeyManager = new UGlobalHotkeys(this);
    hotkeyManager->registerHotkey(hotkey);

    connect(hotkeyManager, &UGlobalHotkeys::activated, [&](size_t id){
        value_++;
        QString text = QString::number(value_);
        ui->label_2->setText(text);
    });

new UGlobalHotkeys(this);として、オブジェクトを確保していますが、this(MainWindow)と紐付いているので、メインウインドウが終了するときに、一緒に削除されます。