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

Jérôme Godbout jerome at bodycad.com
Thu Mar 31 15:28:30 CEST 2016


Just a thought, you may try the Qml Shortcut component:
http://doc.qt.io/qt-5/qml-qtquick-shortcut.html
Not sure about the Shortcut think, I haven't play around too much with it
yet.
Keep a model and the current index of the column and is edit mode.

import QtQuick 2.4
import QtQuick.Window 2.2

Window {
    id: window_
    width: 800
    height: 600
    visible: true

   property currentIndex: 0
   property editMode: false
   Shortcut
    {
      sequence: StandardKey.NextChild // Change for the actual key wanted
      onActivated:
      {
          if(editMode)
              ++myModel[currentIndex].value;
          else
              currentIndex = (currentIndex + 1) % myModel.length; // wrap
around
      }
    }
    // Add other shortcut here to enter/exit editMode: editMode = !editMode
    // previous:  currentIndex = (currentIndex - 1 + myModel.length) %
myModel.length;

   property list<QtObject> myModel:
   [
       QtObject
       {
          property string name: 'meters'
          property int value: 3
       },
       QtObject
       {
          property string name: 'centimeters'
          property int value: 10
       }
   ]
   Row
   {
     spacing: 30
     Repeater
     {
         id: repeater_
         model: window_.myModel
         MyColumn // do the highlight
         {
             selected: window_.currentIndex == index
             editMode: selected && window_.editMode
             value: modelData.value
             name: modelData.name
         }
     }
   }
}

Would be more neat I think, and way easier to maintain or add/remove stuff.
You could have a base object for each entry of the model that have default
property too.

On Thu, Mar 31, 2016 at 8:37 AM, Elvis Stansvik <elvstone at gmail.com> wrote:

> 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
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.qt-project.org/pipermail/interest/attachments/20160331/86413fde/attachment.html>


More information about the Interest mailing list