View Full Version : setFocus() , grabKeyboard(), or event filter?

6th September 2016, 10:24

I am developing a research application for motion control and one of the key features of this software is manual control of a moving vehicle using the arrow keys. Now, keyboard handling in Qt is set up in a way that the focused widget receives the keyboard input first, and then I believe it passes it on to its parent if it ignore()s the event. The issue is that standard elements such as sliders, spinners, dropdowns and scroll areas all consume the arrow keys, and so when the focus is on such an element, I cannot steer my vehicle. So I will have to do something in order for the arrow keys to do what I want them to do no matter where the keyboard focus is. In fact, I am aiming at a solution where with the press of a button, say "K", I can switch to a mode where the arrow keys *always* steer the vehicle no matter where the focus is, and when pressing "K" again, I switch back to the usual way of things and can enjoy ticking sliders with the arrow keys.
I identified three possible solutions. I can either setFocus() on the main widget where my arrow key presses are handled, I can grabKeyboard() in the main widget, or I can install the main widget as an event filter on the QApplication object.

1. setFocus(): First of all the "K" has to be ignored by all widgets in order to be routed up to the main widget (this seems to be the case), where then in the keyPressEvent() I can simply call setFocus(). Then the arrow keys would be routed into the main widget, into the same keyPressEvent() that handles the arrows keys, too, of course. The drawback is that I take the focus away from where it was before. So either I accept that, or add the complication of remembering where the focus was and passing it back there when "K" is pressed again.

2. grabKeyboard(): Essentially the same as the setFocus() method, I grabKeyboard() when "K" was pressed and releaseKeyboard() when it was pressed again, and the focus stays where it is. This sounds better than option 1, except that fishy things happen when I switch to a different window while the keyboard is grabbed in my Qt application. Any thoughts?

3. Installing a global event filter. I would then use the main widget as an event filter for all events. This would make sure that nothing else can use "K", which is good. It also seems relatively straight forward to either take the arrow key press when "K" is on, or just leave it be when it is off. Only the respect of doing such a global thing and not knowing what unforeseen consequences it may have motivates me to ask this question first.

Any thoughts?


6th September 2016, 10:37
I would go for the global event filter, maybe even as a plain QObject subclass for only the purpose of controlling the car.


6th September 2016, 11:05
Works like a charm and it took less time than writing up my first post. I don't know what the hell I'm doing.