У процесі вивчення питань із глобальними хоткеями для Linux та Windows я написав свій велосипед для швидкої реєстрації хоткеїв. бібліотека, що вийшла, називається QGlobalShortcut і викладена на GitHub під ліцензією LGPLv2. Бібліотека підтримує платформи Windows і Linux/Unix (які використовують X11)
Логіка роботи класу QGlobalShortcut, який надається цією бібліотекою, схожа на логіку роботи класу QShortcut, хоча явно не дотягує до даного класу за рядом параметрів, але головне, що виконує свою основну функцію. Зокрема, зареєструвати глобальний HotKey і надіслати сигнал про його активацію.
На даний момент для використання бібліотеки необхідно помістити заголовні файли та файли вихідних кодів у Ваш проект, а також прописати додаткову інформацію у профайлі проекту.
Отримати бібліотеку
Налаштування проекту
Бібліотека складається з одного заголовного файлу та двох файлів вихідних кодів залежно від платформи (Windows, X11). Крім README і т.д.
Бібліотека використовує стандарт мови C++11, тому необхідно конфігурувати проект на цей стандарт або вище. Для linux/unix необхідно використовувати модуль x11extras, який швидше за все необхідно встановити окремо, оскільки Qt за замовчуванням не має в поставці даного модуля. Також необхідно буде конфігурувати проект використання бібліотек для роботи з XLib і XCB.
CONFIG += c++11 linux { QT += x11extras CONFIG += link_pkgconfig PKGCONFIG += x11 } win32: SOURCES += win/qglobalshortcut.cpp linux: SOURCES += x11/qglobalshortcut.cpp HEADERS += qglobalshortcut.h
Громадські функції
ярлик QKeySequence()
Метод повертає встановлену послідовність поєднань гарячих клавіш QKeySequence. Якщо послідовність не встановлена, повертається порожня послідовність QKeySequence("").
bool isEmpty()
Метод перевіряє, чи встановлена послідовність гарячих клавіш чи ні.
bool isEnabled()
Метод перевіряє, включений хоткей чи ні. Поєднання гарячих клавіш може бути встановлене, тоді isEmpty() повертатиме true, але їх спрацювання може бути вимкнено. Тобто сигнал активації хоткею не генеруватиметься.
bool setShortcut(const QKeySequence &keySequence)
Метод є слотом та встановлює послідовність гарячих клавіш. При цьому, якщо QKeySequence містить кілька сполучень клавіш, всі вони будуть зареєстровані.
bool unsetShortcut()
Метод є слотом та видаляє поєднання гарячих клавіш, якщо воно було встановлено.
void setEnabled (увімкнено bool)
Метод є слотом і служить для включення та вимкнення активації поєднання гарячих клавіш.
Сигнали
void activated()
Сигнал активації хоткея, спрацьовує тоді, коли хоткей встановлений та включений.
Використання
#ifndef MAINWINDOW_H #define MAINWINDOW_H #include <QMainWindow> #include "qglobalshortcut.h" namespace Ui { class MainWindow; } class MainWindow : public QMainWindow { Q_OBJECT public: explicit MainWindow(QWidget *parent = 0); ~MainWindow(); public slots: void slotFirst(); void slotSecond(); private: Ui::MainWindow *ui; QGlobalShortcut *shortcutFirst; QGlobalShortcut *shortcutSecond; }; #endif // MAINWINDOW_H
#include "mainwindow.h" #include "ui_mainwindow.h" #include <QDebug> MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWindow) { ui->setupUi(this); shortcutFirst = new QGlobalShortcut(this); connect(shortcutFirst, &QGlobalShortcut::activated, this, &MainWindow::slotFirst); shortcutFirst->setShortcut(QKeySequence("Ctrl+E")); shortcutSecond = new QGlobalShortcut(this); connect(shortcutSecond, &QGlobalShortcut::activated, this, &MainWindow::slotSecond); shortcutSecond->setShortcut(QKeySequence("Ctrl+G")); } MainWindow::~MainWindow() { delete ui; } void MainWindow::slotFirst() { qDebug() << "First"; } void MainWindow::slotSecond() { qDebug() << "Second"; }
Рекомендації до застосування
При створенні екземпляра класу QGlobalShortcut створюється nativeEventFilter, який встановлюється на весь додаток. При цьому кількість фільтрів у додатку не обмежена (тобто Ви можете створити будь-яку кількість глобальних хоткеїв за допомогою даного класу), але фільтр встановлений останнім спрацьовуватиме першим. При цьому використовувати цей клас можна в будь-якому місці програми.
При цьому важливо розуміти, що при використанні даного класу не можна бути точно впевненим, в якій саме послідовності будуть встановлені всі фільтри, що може впливати на продуктивність програми, в якій використовується перевірка інших подій операційної системи, а не глобальних гарячих клавіш. Тобто, якщо Ви вже використовуєте клас, успадкований від QAbstractNativeEventFilter, і встановили даний фільтр на додаток для обробки низки подій системи за допомогою нього, то, можливо, має сенс не використовувати бібліотеку в лоб, а застосувати частину програмного коду бібліотеки у Вашому вже існуючий клас.