Global hotkeyDaniele Esposti's Blog, in 03 May 2012
Let start by explaining the goal: we want to send a custom signal when the user press a combination of keys. Sound pretty easy, your are already thinking to override the
keyReleaseEvent() virtual methods of your
QMainWindow with your custom code.
It’s a fair solution, but not the so elegant, and what’s happen if you have more than one
QMainWindow instances or none at all?
To solve the problem once for all I’ll use a custom
QApplication instance to catch the key press and release and to emit the signal.
QApplication is a singleton and easy to retrieve its instance’s pointer anywhere in your application; also it process all the events, including keyboard events, so we can plug our event filter to catch the hotkey.
I’ll start by defining a subclass of
QApplication with our custom signal:
notifyHotkeyStatus() method will emit a
hotkey(bool) signal once when the hotkey is pressed (with a
true value) and once when the hotkey is released (passing a
Now I create a lame
QMainWindow subclass which changes its background color when the hotkey is pressed. I’ll show only the relevant parts, the rest of the code is the default stuff generated by Qt Creator:
As you see I’m retrieving a pointer to the
QApplication by using the qApp macro and connecting the
onHotkey() slot at the
hotkey(bool) signal. That’s all.
And now the interesting part: our event filter which will catch the hotkey press and release events. The header is pretty simple:
The implementation instead needs to be explained step. The constructor just initialise the
hotkey private flag, I’ll explain its purpose later.
The first part of the
eventFilter() method implementation just casts the parent and exits if it’s not a instance of
Now I check if the event is a
KeyPressEvent and if the current modifiers flags matches our hotkey.
I’m using the value of the
hotkey flag to emit the
hotkey(bool) signal only once on key press; no more
hotkey(bool) signals will be emitted until the hotkey will be release.
The key release event check its specular to the key press event check: I check if the hotkey was pressed before and, if the current modifiers doesn’t matches the hotkey, we emit the
hotkey(bool) signal and reset the flag.
The last line of code of the
eventFilter() is trivial:
Now it’s time to put al together and run a small test. I’ll create a
MyApplication instance with my custom event filter, and two main windows instances as demonstration:
Run the code and when you will press the hotkey combination (SHIFT+CTRL or SHIFT+CMD on macOS) the windows’ background will change to green.
Well, anyway I didn’t all this work just to change a window’s backgrounds :-)!
Here you can download the source code of this article. Have fun with it!