Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. QML and Qt Quick
  4. [Solved] Focus, child items, and the end of my wits
QtWS25 Last Chance

[Solved] Focus, child items, and the end of my wits

Scheduled Pinned Locked Moved QML and Qt Quick
6 Posts 2 Posters 2.4k Views
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • S Offline
    S Offline
    sohail
    wrote on last edited by
    #1

    Hey guys,

    I've got an example here where I'm trying to find the "best" way to do this. I've got a QML window with 2 elements: a text box and a listview. You guessed it, it's a search window.

    I can easily assign focus programatically to 'scope' by setting scope.focus = true. The problem occurs when I try and figure out a decent way for setting the right focus when clicking on an element in the listview. The only way I can think of this happening in the delegate is by doing some parent.parent.parent.parent gibberish but that is very fragile as it depends on the hierarchy and I'm trying to create a re-usable ListView for my app.

    Can anyone think of a pattern that would help me accomplish what I'm trying to do here?

    Thanks!

    @
    import QtQuick 2.1
    import QtQuick.Controls 1.0
    import QtQuick.Layouts 1.0
    import QtGraphicalEffects 1.0

    ApplicationWindow {
    width: 600
    height: 300

    id: win
    
    ColumnLayout {
        anchors.fill: parent
    
        Text {
            Layout.fillWidth: true
            text: scope.focus ? "ListView has focus" : "ListView doesn't have focus"
        }
    
        TextInput {
            Layout.fillWidth: true
            focus: true
        }
    
        /* This is defined somewhere else, independent of the focus scope below */
        Component {
            id: myDelegate
            Text {
                text: modelData ? modelData.name + ' (' + modelData.age + ')' : ''
                width: parent ? parent.width : 0
                height: 32
                MouseArea {
                    anchors.fill: parent
                    onClicked: {
                        /* how best to set the rectangle enclosing the focus scope to have
                           focus? */
                        /* This is the effect I want, but without referring to "scope" directly */
                        /* scope.focus = true */
                        /* Another way */
                        var scopehack = parent.parent.parent.parent.parent.parent.parent.parent.parent.parent
                        console.log(scope,scopehack)
                        scopehack.focus = true
                    }
                }
            }
        }
    
        /* Actually a Flipable */
        Rectangle {
    
            id: theflipable
            color: "#AABBCCDD"
            Layout.fillWidth: true
            Layout.fillHeight: true
    
            FocusScope {
                id: scope
                anchors.fill: parent
                focus: true
    
                Rectangle {
                    anchors.fill: parent
                    color: "transparent"
                    radius: 3
    
    
                    RectangularGlow {
                        anchors.fill: parent
                        visible: scope.activeFocus
                        glowRadius: 10
                        spread: 0.2
                        color: "red"
                        cornerRadius: 13
                    }
    
                    ScrollView {
                        anchors.fill: parent
                        /* The following two properties allow us to use keyboard navigation
                           within the ListView. See
                           https://bugreports.qt-project.org/browse/QTBUG-31976
                           */
                        flickableItem.interactive: true
                        focus: true
    
                        ListView {
                            anchors.fill: parent
                            boundsBehavior: Flickable.StopAtBounds
                            clip: true
                            focus: true
                            model: ListModel{}
                            delegate: Loader {
                                width: parent.width
                                sourceComponent: myDelegate
                                property variant modelData: model
                            }
    
                            highlightFollowsCurrentItem: true
                            highlight: Rectangle {
                                width: parent ? parent.width : 0
                                color: "#3465A4"
                            }
                            highlightMoveDuration: 250
    
                            Component.onCompleted: {
                                for(var ii = 0; ii < 250; ++ii) {
                                    model.append({'age':ii,'name':'Bopinder ' + ii})
                                }
                            }
                        }
                    }
                }
            }
        }
    }
    

    }
    @

    1 Reply Last reply
    0
    • X Offline
      X Offline
      Xander84
      wrote on last edited by
      #2

      what is the problem with setting the focus via id.focus = true or id.forceActiveFocus()? I don't understand why you don't like that, still better than parent.parent.parent.parent.parent.focus = true I guess :D

      Edit: if you don't know the item id at that point why not setting it from the outside to a custom property or something?
      @
      property Item focusTarget
      @
      and than from outside just set it to some id you want to get focus when you click on the delegate
      @
      yourComp.focusTarget = scope
      @

      1 Reply Last reply
      0
      • S Offline
        S Offline
        sohail
        wrote on last edited by
        #3

        Because the problem I have is something like this:

        @
        MyTopLevelWindow {
        ColumnLayout {
        SearchBar {}
        RectangularGlow{...visible: searchResults.activeFocus }
        SearchResults{ id: searchResults}
        }
        @

        The actual ListView is way down, deep somewhere in the guts of SearchResults because I have a particular implementation I want to use. The focus is assigned to that but the rectangular glow effect is on the searchResults container. Does that make sense?

        1 Reply Last reply
        0
        • S Offline
          S Offline
          sohail
          wrote on last edited by
          #4

          It looks like ListView.forceActiveFocus does what I need. Gonna do some testing.

          1 Reply Last reply
          0
          • X Offline
            X Offline
            Xander84
            wrote on last edited by
            #5

            see my edit, maybe that helps or I still don't know what the problem is the Item ids are usually accessible from everywhere unless its a separate qml file but then you can simple use an property alias or what i suggested maybe?

            1 Reply Last reply
            0
            • S Offline
              S Offline
              sohail
              wrote on last edited by
              #6

              The key points to getting this was:

              Understanding that FocusScope is a chain going up ancestry

              I needed to was to forceActiveFocus on the child I wanted to get the active focus so it would bubble up to the parent that eventually had the RectangularGlow attached. Simply setting child.focus = true was not sufficient.

              Thanks for the quick help Xander84!

              1 Reply Last reply
              0

              • Login

              • Login or register to search.
              • First post
                Last post
              0
              • Categories
              • Recent
              • Tags
              • Popular
              • Users
              • Groups
              • Search
              • Get Qt Extensions
              • Unsolved