Automatically passing focus around a grid
-
I'm building a UI that will be controlled by touch, mouse, keyboard, and gamepad.
Many screens have grids of buttons. I want to be able to use the dpad to move focus between items, and then use the Ⓐ button to invoke the button.
- Is there any mechanism for automatically passing focus between items in a focus group based on direction? For example, I'd love it if
FocusGroup
had methods likemoveFocusLeft()
,moveFocusRight()
,moveFocusUp()
,moveFocusDown()
. Do such methods exist anywhere, such that I could map dpad presses?- My current solution is to create state machines which each screen that pass focus around. This works, but is cumbersome to create and maintain.
- Is there any mechanism to register the Ⓐ button to trigger the focused button? With the keyboard, I can tab to a button and hit space to invoke it, with no special event handling for the spacebar.
- My current workaround is to explicitly handle the Ⓐ button events and run this code:
if (root.activeFocusItem.clicked) root.activeFocusItem.clicked();
This works, but seems fragile.
- My current workaround is to explicitly handle the Ⓐ button events and run this code:
- Is there any mechanism for automatically passing focus between items in a focus group based on direction? For example, I'd love it if
-
Solution I'm using now:
-
Use the
KeyNavigation
attached properties on all buttons in QML to specify where focus should move when the arrow keys are pressed. With that keyboard arrow keys pass focus around. Dpad also seems to workout of the box for this; not sure why. -
Use the (undocumented)
GamepadKeyNavigation
object to cause the A button to act the same as pressing the space key.
Here's an example of a simple 2x2 grid of buttons where focus gets moved by arrow keys and gamepad, and you can use space or 'A' button to press a button:
import QtQuick 2.6 import QtQuick.Window 2.2 import QtQuick.Controls 1.4 import QtQuick.Layouts 1.3 import QtGamepad 1.0 Window { width:800; height:480 visible: true title: "Grid Navigation Test" Gamepad { id: gamepad deviceId: GamepadManager.connectedGamepads.length > 0 ? GamepadManager.connectedGamepads[0] : -1 } GamepadKeyNavigation { gamepad: gamepad active: true buttonAKey: Qt.Key_Space } GridLayout { columns: 2 Button { id:b1; text:"B1" focus: true KeyNavigation.right: b2 KeyNavigation.down: b3 } Button { id:b2; text:"B2" KeyNavigation.left: b1 KeyNavigation.down: b3 } Button { id:b3; text:"B3" KeyNavigation.right: b4 KeyNavigation.up: b1 } Button { id:b4; text:"B4" KeyNavigation.left: b3 KeyNavigation.up: b2 } } }
-