Qt/QML: How to activate a Shortcut from C++? - c++

I have an application which receives input from a serial port and interprets them as key events. The key events are created in C++ and sent to QGuiApplication::focusWindow() with qApp->sendEvent.
The GUI is implemented in QML and has been handling input through key event handlers. I would like to start using the Shortcut QML class to handle cases where I want behavior regardless of which object has focus.
I've discovered that Shortcuts which respond to a real keyboard will not respond to qApp->sendEvent, nor do they respond to qApp->postEvent.
Getting the behavior I want to reliably occur without Shortcut would be a real pain - is there I way I can handle my synthetic events which will make them visible to Shortcut?

Qt shortcut objects work through parts of the Qt system which are not part of the regular API, but are exposed to QPA. Specifically, QWindowSystemInterface::handleShortcutEvent, which takes as arguments the current focus window and most of the information encapsulated in a QKeyEvent.
// A helper to send a QKeyEvent to shortcuts
bool handleShortcutEvent(const QKeyEvent &ev, QWindow *focusWindow) {
return QWindowSystemInterface::handleShortcutEvent(focusWindow, ev.timestamp(), ev.key(), ev.modifiers(), ev.nativeScanCode(), ev.nativeVirtualKey(), ev.nativeModifiers(), ev.text(), ev.isAutoRepeat(), ev.count());
}
// in my key event generating function
if(!handleShortcutEvent(event, focusWindow))
qApp->sendEvent(focusWindow, &event);

Related

How does View get updated behind the scenes?

So when I use a setText() on a QLabel for example, Qt automatically updates the view/gui for me and the new text is shown, but what happens behind the scenes? Is there an update function that gets called automatically when using functions like setText()?
Thanks!!
You should check the basic documentation in this link.
The internal system is a little bit more complex but in general, it follows the observer pattern. This mechanism allows the detection of a user action or changing state, and respond to this action.
Low-level interactions, like refreshing the screen are implemented via the Event System
In Qt, events are objects, derived from the abstract QEvent class, that represent things that have happened either within an application or as a result of outside activity that the application needs to know about. Events can be received and handled by any instance of a QObject subclass, but they are especially relevant to widgets. This document describes how events are delivered and handled in a typical application.
So, regarding the display process, there is a dedicated event. A QWidget object handles/subscribe to a PaintEvent, see QWidget::paintEvent.
This event handler can be reimplemented in a subclass to receive paint events passed in event. A paint event is a request to repaint all or part of a widget.
When you call, QLineEdit::setText(), the widget will be repainted the next time a display event is triggered, based in the OS configuration, refresh rate, etc.
For high-level interactions, Qt uses a similar pattern based in the signal/slot mechanism:
Observer pattern is used everywhere in GUI applications and often leads to some boilerplate code. Qt was created with the idea of removing this boilerplate code and providing a nice and clean syntax, and the signal and slots mechanism is the answer.

QTextEdit receives Control Key doesn't pass to main window

I have a QTextEdit on my QMainWindow. I have overridden my main window keyPressEvent method and put a few hotkey handlers in there (ie: Ctrl+J, Ctrl+K). These hotkeys are global to the application.
The issue I have is that when the QTextEdit widget has focus, these key presses seem to be consumed by the widget and never seen by the form. The interesting thing is that these key combos do nothing in the QTextEdit.
How can I have the QTextEdit ignore key combinations that it has no behaviour associated with? Alternatively, how might I accomplish my goal in Qt?
Whichever widget has the keyboard focus will nominally consume all keyboard events. There's no notion of an "unhandled" keyboard event. Qt's event semantics for keyboard events don't work that way.
You need to use a QShortcut. Internally, it acts as an application-wide event filter for keystroke sequences, it's tied into the private implementation of QApplication. The only other way for you to do it would be to act as an application-wide event filter that acts on keystroke events.

Handle EVT_CHAR in wxFrame or wxDialog

As we all know, EVT_CHAR is a basic event which don't propagate to wxTopLevelWindow(wxFrame and wxDialog).
But I have a wxDialog without any wxWidgets controls on it, and need to handle user keyboard input (handle EVT_CHAR event).
I saw the wiki about catch key events globally, but it's not work on EVT_CHAR event as EVT_CHAR event need to be translated to get user input
And I have try to have wxDialog a hided children wxWindow which foward EVT_CHAR to its parent wxDialog. It works on Windows platform, and not on OSX which is my target platform.
Is there a way to implement it ?
Why do you need to handle all keyboard entry in the dialog itself? There are two typical cases for this that I know of: either you want to handle the key presses in several different controls in the same way, or you need to handle some particular key press (e.g. WXK_F1) in all controls. The former can be done by binding the same event handler to several controls. The latter -- by using accelerator table with an entry for the key that you want to handle specially.
Finally, I implemented what I want according to this:
http://trac.wxwidgets.org/ticket/15345
In wxWidgets 3.0, wxNSView implementes NSTextInputClient protocol, which makes every widgets can handle EVT_CHAR correctly.
But EVT_CHAR still cannnot be handle by wxDialog or wxFrame, because of some call of IsUserPanel() function. So I commented some call of IsUserPanel to make it work for me.

How to get notified of textbox focus?

Using a Windows 7 touch device Windows shows this little touch-keyboard indicator (tabing this will bring up the touch on screen keyboard) when you tab/focus a textbox or kind of input field (Notepad etc.).
I want to write an application that gets notified when exactly that happens, a textbox (etc.) gets focused (no matter which application).
Are applications informed about focusing in other applications, do I need to hook something?
Is there a way in doing so in c++?
I believe the SetWinEventHook function and specifically the EVENT_OBJECT_FOCUS event is what you are looking for.
From the MSDN description:
An object has received the keyboard focus. The system sends this event for the following user interface elements: list-view control, menu bar, pop-up menu, switch window, tab control, tree view control, and window object. Server applications send this event for their accessible objects.
The hwnd parameter of the WinEventProc callback function identifies the window that receives the keyboard focus.

QShortcut in console application (no GUI)

Is it possible to use QShortcut in a console QCoreApplication? I don't have any QWidget objects to pass to QShortcut's constructor, I want the signal to be emitted when the user presses a key and the console window has focus.
If such approach is not possible what (prefferably portable) alternatives do I have?
Thank you in advance!
I'm not sure this is at all possible, because keyboard events in the sense usually used in Qt are delivered to windows/widgets, by the underlying OS windowing system. There's a reason why QShortcut requires a widget parent.
When you're in the terminal, you have to explicitly read the terminal to get keys.
Fortunately, that's easy to do. Use QTextStream to read from stdin in a separate thread, and translate interesting keystrokes to signals or events.
Do note, however, that in consoles some special keystrokes won't be delivered to you as-is. It depends a lot on the console, of course.