What is difference between hotkey, shortcut and accelerator key? - c++

What is the difference about them?
In Qt, if I have a hotkey for QPushButton, I can make it by "Alt + ?", but if it's for qaction, I can press "?" only

In Windows, an accelerator key is application global; e.g. Alt+F4.
A shortcut key is part of the name of a menu item or button, where it can be underlined, and is available (without modifiers) when that menu item or button is directly available.
From Microsoft:
A hot key is a key combination that the user can press to perform an action quickly. For example, a user can create a hot key that activates a given window and brings it to the top of the z-order.
which seems to indicate that hot keys are system global.
To sum up:
shortcut key = no modifiers, local in menu or (for button) in window
accelerator key = typically with modifier, application global
hot key = apparently system global
I don't know about specific meanings in Qt; for that see the Qt documentation.

Alf's answer is correct for Windows applicability. Your terms you mention (hotkey/shortcut/accelerator) don't sound familiar from a pure Qt point of view.
In Qt you can elect to handle key sequences yourself or you can use Qt's own simplification method. Either way you must remember that Qt itself targets many platforms on which a key combination may or may not make sense. The classic Alt + F4 makes sense on a keyboard, but on a mobile device you don't have an Alt modifier or an F4 key. What you really want is a way of specifying a generic close the application shortcut. This problem is multiplied because the symbol may be available but the key sequence to reach it might be different on other keyboard layouts. This section of the documentation provides a good example.
Qt handles this with class QKeySequence. The very clever Qt developers have provided an easy way of defining common user actions and those actions will use key combinations that are default to the target platform. It does this using enum QKeySequence::StandardKey and in the close the application example, you could use this like so:
QAction exitAction;
exitAction.setShortcut(QKeySequence(QKeySequence::Quit));
This is all explained in the documentation. There are a two other modifiers (shortcutContext() and softKeyRole()) which can be applied to QActions which effect their application in more advanced ways.
You are also free to assign your own shortcuts using something like:
QAction helpAction(tr("&?"));
helpAction.setShortcut(QKeySequence(tr("ALT+?")));
The first line applies the (translated) text "?" to the action which will appear as its text on a menu or button. Note that the question mark symbol might not be the right symbol in all languages so the translate method allows a translator to assign a more appropriate symbol if required. The ampersand symbol means the character immediately after will be the short-cut key when the menu is active.
The second line assigns the (translated) shortcut of Alt + ? and in this example the Shift modifier will be handled by the platform if required. Again, the tr() method allows the translator to specify a more appropriate shortcut if available.
In response to teukkam's comment:
If you mean you simply want your button to be triggerable by a keystroke whether its modified by Alt or not then you could do something like:
QPushButton* yourButton; // assign this pointer yourself
yourButton->setText(tr("&Process"));
yourButton->setShortcut(tr("p"));
In this example, the ampersand in setText() does the same as the previous example, and the translate function is used in the same way.
The setShortcut() method just uses the letter "p" so should work now with or without the Alt modifier. A quick skim of the documentation suggests this will work with or without the Shift modifier as the letters in a key sequence are apparently case-insensitive.
Also, P would be a bad choice as its often assumed to be the print command.
A final note if you're defining hard coded short cuts, make sure they work on all your target platforms!

In Windows:
HotKey
Keyboard key or combination of keys that execute a command in a given context.
Shortcut
Multi-key HotKey with no menu navigation restrictions nor gui elements required.
AccessKey
Single key HotKey which command is to activate a visible command control
(requires gui element) that is captioned/labeled with the corresponding hotkey letter underscored.
Accelerator Keys
Multi-key HotKey which command is to activate a command control (requires gui element) regardless of its visibility.

Related

Qt(c++) Keybinding with button(for my developing application)

I want to write a function that will work with keybinding for the application I am developing on the Qt platform, but I could not find any example that will work for me, like the picture I added from the discord application, can you help me?
Discord keybinding
You question is slightly fuzzy, there are a few aspects associated with key bindings.
At the start of the application, you can assign default shortcut keys to actions and menus, see the documentation on QAction, QShortcut, QMenu.
If you need a dialog which allows changing a key binding, you can easily create a dialog yourself. See the documentation on QKeySequenceEdit which helps you entering a new shortcut key sequence for an action.
Last but not least, you need to bind your modified key sequences to your actions. You can do this by deriving a class from QAction. Find these actions by searching all objects with mainWindow->findChildren<YourActionClass*>()
and modify the keyboard shortcut with the results from your dialog.
This derived class could also store the default binding, the icon (your users might like to modify icons perhaps) etc.
All this is quite straight forward.
If you want user to hit a key combination for a selection then just create a class inheriting QLinEdit (even QLabel would work) and override keyPressEvent,
void QLineEdit::keyPressEvent(QKeyEvent *event);
and then use QKeyEvents function to get key and modifiers (shift, ctrl etc.). Just read the Qt Docs about it. Depending on the key and modifiers, write the modifier name + key's text (e.g. Ctrl + N).
To hold actions (QAction), just use std::map<QString,QAction*> or QMap<QString,QAction*> and register/add your QAction objects in the map and assuming your class' name is MyClass and it has getKeyString() , to return key combination as QString, then you will just do,
QString str = MyClassObj.getKeyString();
QKeySequence ks(str);
actionMap.at("NewFile")->setShortcut(ks);

Windows API - registering a hotkey with multiple keys combination

So for example I can easily register a hotkey that is a combination of Shift, Alt (Mod keys) and Up arrow:
RegisterHotKey(NULL, TOP, MOD_SHIFT | MOD_ALT, VK_UP);
This works just fine but what I'm after is registering a hotkey with the same keys as above PLUS another normal key like Left arrow, so the combination would be Shift, Alt, Up arrow, Left arrow.
There isn't space in the function for another argument, and I tried doing a bitwise OR for the Up and Left arrow keys like
VK_UP | VK_LEFT
... but it's not working. If anyone encountered this problem before or knows how I proceed please help!
Windows hotkeys don't support multiple (non-modifiers) keys. You cannot bitwise OR multiple VK_* values, only MOD_* values can be combined.
If you desperately need this feature then you have to use a low-level keyboard hook and track the keys yourself. Hooking affects global system performance and should be avoided if possible.
If you decide to do this you have to remember that Windows users are not used to pressing hotkeys this way, only menus allow a somewhat similar pattern but you don't have to hold the Alt modifier to make those work. You must also remember to test your hook with StickyKeys and other accessibility features...

Which is better for MFC application hot key or Accelerator?

We have MFC application which has around 10 image buttons to which we want to provide shortcut keys. Shortcuts will be customizable. I have implemented shortcuts (with no customization right now) with hotkeys using ON_WM_HOTKEY() message.
After searching through Goolge I am little confuse. For example, this question is suggesting hotkey is global for OS, and Accelerator is global for application.
Which one I should use with my application. My shortcut keys will be like Ctrl + Shift + A, and will be customizable.
Secondly, where to keep them. Is it usual to store shortcuts in Windows Registry?
Hotkeys added via RegisterHotKey (or its equivalent in MFC) are definitely system global and you should not use them to trigger functions in your program unless you specifically want the user to be able to trigger them from anywhere.
(e.g. your application might be a screenshot app, and so triggering a function from outside it would make sense)
Normally though you should use accelerators to add keyboard bindings for toolbar buttons etc.
Where you store them is up to you - I would say you should store them wherever you store the rest of your application's configuration data.
The difference between an accelerator key and a hotkey is as the provided link states; an accelerator key press is registered whenever the registered key combination is pressed while the application has focus (normal behaviour). However if you want to register a key combination that works even if the user is using another application while your application is in the background; go for hotkey. Applications that commonly uses this are clipboard managers, screen grabbers and launchers.
Storing configuration in the registry is what I would recommend, however you could also use configuration files stored in the users profile directory.

How can I prevent RegisterHotKey from blocking the key for other applications?

I am writing a win32 application that needs to take hotkeys while not on focus(it runs in the background without drawing a window). I use RegisterHotKey to assing a few keys but that blocks the for every other process. For example I assign the 'c' key and when I press it in notepad nothing happens.
RegisterHotKey() registers global hotkeys. Hotkeys are processed before regular keyboard input processing, meaning that if you register a hotkey successfully, pressing that key will result in you getting your hotkey message rather than the app with focus getting the normal WM_KEYDOWN/WM_CHAR messages. You have effectively blocked other apps from seeing that key press.
This is by design.
Obviously the solution to avoid clashes like you describe is to not register a hotkey that other applications may use. If you register C without any qualifiers as a hotkey, then no other program will see the C key being pressed. Instead you should use qualifiers like Ctrl/Shift/Alt to prevent your hotkey from interfering with the normal use of the keyboard.
There is no way to register a hotkey that's global unless some other program is active. If you want to achieve the situation where, say, your hotkey works while the desktop is active but nothing else is, you could use a message hook to inject code into the desktop's process (via SetWindowsHookEx()) and intercept key presses that way. But you can't do it with RegisterHotKey().
I just tried UnregisterHotKey(), simulated the key with keybd_event(), then RegisterHotKey() again. I don't recommend it as a production code, it's probably better to use hooks for that, but as a quick hack I just wanted to say that it works.
GetAsyncKeyState()
can be used to determine if certain keys are pressed, even when the program is running in the background.

Capturing keyboard input without focus on the programwindow

I am doing a VoIP client and I want to start/stop on WM_KEYDOWN and WM_KEYUP messages for a certain input, say K. When the main window has focus, this is np, but how do I enable it outside of the window? For example, if the window is not in focus and I'm just looking at the desktop or am in a videogame. How does one perform something like this? I am not sure where to begin.
Also -- I guess you somehow has to poll every input even outside the program, is that expensive?
win32 c++ btw
You need to install keyboard hooks: http://msdn.microsoft.com/en-us/library/ms644990(v=VS.85).aspx
This can be very troubling though for every running application if something steals its keyboard messages.
I don't think you want this - if I'm typing a document into Word and I hit K, I'm going to be very angry when your application pops up instead of a "k" appearing in my document.
Windows allows you to assign shortcut keys to an icon on the desktop, but it limits them to the function keys or to combinations containing both Alt and Ctrl. Right-click on a desktop icon and go to Properties, and look for the field marked "Shortcut key".