[Interest] Declaratively handle key presses / navigation differently depending on state (QML)

Kristoffersen, Even (NO14) Even.Kristoffersen at Honeywell.com
Thu Mar 31 15:12:02 CEST 2016


I think Connections is what you are looking for:

Connections
{
	id: editingConnections
	target: null

	onRightPressed: ...
	...
	...
}

Connections
{
	id: navigationConnections
	target: Keys

	onRightPressed: ...
	...
	...
}

..

states: [
                    State {
                        name: "editing"
                        PropertyChanges {
                            target: editingConnections
                            target: Keys	//Don't know if this works since the parameter is called target as well. If it doesn't work you'll have to do something like this in editingConnections declaration:
				//target: meters.state === "editing" ? Keys : null
                        }
                        PropertyChanges {
                            target: navigationConnections
                            target: null
                        }
                    }
                ]


-----Original Message-----
From: Interest [mailto:interest-bounces+even.kristoffersen=honeywell.com at qt-project.org] On Behalf Of Elvis Stansvik
Sent: 31. mars 2016 14:38
To: interest at qt-project.org Interest <interest at qt-project.org>
Subject: [Interest] Declaratively handle key presses / navigation differently depending on state (QML)

Hi,

I'm working on an item representing a number to be edited by the user.

My input is quite limited (only Left, Right and Enter, where Left and Right is actually the turning of a wheel), so the idea is to let the user navigating to the item with Left/Right, which will give it focus.
If the user then presses Enter, the item enters and "editing" state.
In the "editing" state, Left and Right will increase/descreas the number, and pressing Enter again will exit the "editing" state, returning to the default state ("").

How can I handle key presses differently depending on state without resorting to procedural code like if/else on the state inside the onXXXPressed handlers? I thought I'd be able to assign to Keys.onXXXPressed inside State { PropertyChanges { ... }, but the property is not recognized there (I'm guessing because it's an attached property..?).

Also, the KeyNavigation.left/right/etc. is a convenient way to do the navigation between items, but it seems incompatible with the Keys.onXXXPressed handlers? I thought I'd be able to skip accepting the key even in a Keys.onXXXPressed handler, and have it pass through to the KeyNavigation.xxx handler...? (I can do the navigation with
someItem.forceActiveFocus() instead, but it's more typing and more error prone).


Below is a working but rather ugly example of two numbers that can be edited this way. One can navigate between the numbers with Left/Right, and toggle "editing" mode with Enter (in which Left and Right controls the number value instead).

How can I make this example more declarative / less ugly? (Besides the obviously putting things in a reusable component).

Example:

import QtQuick 2.4
import QtQuick.Window 2.2

Window {
    width: 800
    height: 600
    visible: true

    Row {
        spacing: 30
        Column {
            Text {
                text: "Meters"
            }
            Text {
                id: meters
                text: value
                font.underline: activeFocus
                font.pixelSize: 100

                property int value: 3

                focus: true

                states: [
                    State {
                        name: "editing"
                        PropertyChanges {
                            target: meters
                            color: "green"
                        }
                    }
                ]

                Keys.onReturnPressed: {
                    if (state == "")
                        state = "editing"
                    else
                        state = ""
                    event.accepted = true
                }

                Keys.onRightPressed: {
                    if (state == "editing")
                        value++
                    else
                        centimeters.forceActiveFocus()
                    event.accepted = true
                }

                Keys.onLeftPressed: {
                    if (state == "editing")
                        value--
                    else
                        centimeters.forceActiveFocus()
                    event.accepted = true
                }
            }
        }
        Column {
            Text {
                text: "Centimeters"
            }
            Text {
                id: centimeters
                text: value
                font.underline: activeFocus
                font.pixelSize: 100

                property int value: 14

                states: [
                    State {
                        name: "editing"
                        PropertyChanges {
                            target: centimeters
                            color: "green"
                        }
                    }
                ]

                Keys.onReturnPressed: {
                    if (state == "")
                        state = "editing"
                    else
                        state = ""
                    event.accepted = true
                }

                Keys.onRightPressed: {
                    if (state == "editing")
                        value++
                    else
                        meters.forceActiveFocus()
                    event.accepted = true
                }

                Keys.onLeftPressed: {
                    if (state == "editing")
                        value--
                    else
                        meters.forceActiveFocus()
                    event.accepted = true
                }
            }
        }
    }
}


Thanks for any advice,
Elvis
_______________________________________________
Interest mailing list
Interest at qt-project.org
http://lists.qt-project.org/mailman/listinfo/interest



More information about the Interest mailing list