To work with global HotKey in Qt5 , there is a virtual method nativeEvent . This method replaces the methods winEvent , x11Event , macEvent of Qt 4.8 .
The especiality in the HotKey to Qt is that if the window is not in focus, that is, it is, for example, will be minimized to the system tray, then registered QShortcut simply will not work. It is therefore necessary to work with the global events from the operating system, that is, go to the realization of the platform-specific code in the application to Qt.
RegisterHotKey
In this example Let us examine the option of working with WinAPI. For this we use the function RegisterHotKey.
BOOL WINAPI RegisterHotKey( _In_opt_ HWND hWnd, _In_ int id, _In_ UINT fsModifiers, _In_ UINT vk );
RegisterHotKey parameters
hWnd [in, optional]
Тип:
HWND
A handle to the window that will receive
WM_HOTKEY
messages generated by the hot key. If this parameter is
NULL
,
WM_HOTKEY
messages are posted to the message queue of the calling thread and must be processed in the message loop.
id [in]
Type:
int
The identifier of the hot key. If the
hWnd
parameter is NULL, then the hot key is associated with the current thread rather than with a particular window. If a hot key already exists with the same
hWnd
and
id
parameters, see Remarks for the action taken.
fsModifiers [in]
Type: UINT The keys that must be pressed in combination with the key specified by the uVirtKey parameter in order to generate the WM_HOTKEY message. The fsModifiers parameter can be a combination of the following values.
- MOD_ALT 0x0001 - Either ALT key must be held down.
- MOD_CONTROL 0x0002 - Either CTRL key must be held down.
- MOD_NOREPEAT 0x4000 - Changes the hotkey behavior so that the keyboard auto-repeat does not yield multiple hotkey notifications. Windows Vista: This flag is not supported.
- MOD_SHIFT 0x0004 - Either SHIFT key must be held down.
- MOD_WIN 0x0008 - Either WINDOWS key was held down. These keys are labeled with the Windows logo. Keyboard shortcuts that involve the WINDOWS key are reserved for use by the operating system.
vk [in]
Type:
UINT
The virtual-key code of the hot key.
UnregisterHotKey
Disable keyboard shortcuts.
BOOL WINAPI UnregisterHotKey( _In_opt_ HWND hWnd, _In_ int id );
UnregisterHotKey Parameters
hWnd [in, optional]
Type:
HWND
A handle to the window associated with the hot key to be freed. This parameter should be
NULL
if the hot key is not associated with a window.
id [in]
Type:
int
The identifier of the hot key to be freed.
An example of a HotKey in WinAPI
Create a project to work with HotKey. This project will be present QSystemTrayIcon object class. Let's hide the application in the system tray and check hotkeys. That combination is "ALT + SHIFT + D", for example. In this project, the handler hotkeys will MainWindow. Treatment of combinations of hot keys will be made in nativeEvent.
Check on the selected combination of hot keys will produce via qDebug().
mainwindow.h
#ifndef MAINWINDOW_H #define MAINWINDOW_H #include <QMainWindow> #include <QSystemTrayIcon> #include "windows.h" // Connect WinAPI library namespace Ui { class MainWindow; } class MainWindow : public QMainWindow { Q_OBJECT public: explicit MainWindow(QWidget *parent = 0); ~MainWindow(); protected: // The method for processing native events from the OS in Qt bool nativeEvent(const QByteArray &eventType, void *message, long *result); private slots: void iconActivated(QSystemTrayIcon::ActivationReason reason); private: Ui::MainWindow *ui; QSystemTrayIcon *trayIcon; }; #endif // MAINWINDOW_H
mainwindow.cpp
#include "mainwindow.h" #include "ui_mainwindow.h" #include <QDebug> MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWindow) { ui->setupUi(this); /* System Tray Icon is necessary to the application window is not in focus * */ trayIcon = new QSystemTrayIcon(this); trayIcon->setIcon(this->style()->standardIcon(QStyle::SP_ComputerIcon)); trayIcon->show(); connect(trayIcon, SIGNAL(activated(QSystemTrayIcon::ActivationReason)), this, SLOT(iconActivated(QSystemTrayIcon::ActivationReason))); // Register HotKey "ALT+SHIFT+D" RegisterHotKey((HWND)MainWindow::winId(), // Set the system identifier of the widget window that will handle the HotKey 100, // Set identifier HotKey MOD_ALT | MOD_SHIFT, // Set modifiers 'D'); // We define hotkeys for HotKey } MainWindow::~MainWindow() { delete ui; } bool MainWindow::nativeEvent(const QByteArray &eventType, void *message, long *result) { Q_UNUSED(eventType) Q_UNUSED(result) // Transform the message pointer to the MSG WinAPI MSG* msg = reinterpret_cast<MSG*>(message); // If the message is a HotKey, then ... if(msg->message == WM_HOTKEY){ // ... check HotKey if(msg->wParam == 100){ // We inform about this to the console qDebug() << "HotKey worked"; return true; } } return false; } void MainWindow::iconActivated(QSystemTrayIcon::ActivationReason reason) { switch (reason){ case QSystemTrayIcon::Trigger: !isVisible() ? show() : hide(); break; default: break; } }
Note
To ensure that the project is compiled with MSVC build a set, add the following lines to pro project file:
win32-msvc*{ LIBS += -luser32 }
Conclusion
As a result of this processing will code the global keyboard shortcuts, even if the application window will be hidden in the system tray tray.