Using FocusScope



  • Yesterday a big chunk of my day was lost trying to figure out how FocusScope works, its a tad tricky ;)

    I hit one issue that I'm wondering is a bug (in 4.8) or still a gap in my understanding.

    I have a C++ object that inherits QObject and has several properties.
    @
    Q_PROPERTY(QList<QObject*> myList READ myList NOTIFY myListChanged)
    Q_PROPERTY(QObject* currentItem READ currentItem NOTIFY currentItemChanged)
    @

    the list is shown in something like this
    @
    FocusScope {
    Flow {
    Repeater { model: foo.myList
    Item {
    property bool isCurrent: foo.currentItem == modelData
    focus: isCurrent
    }
    }
    }
    @

    Now, when the list is created (by emitting the signal in C++) the repeater suddenly gets children, as expected. But for some reason nothing gets focus. If I manage to change the currentItem after the view is shown, stuff works properly.
    I had to add this as a child of the Repeater item;
    @
    onItemAdded: {
    if (item.isCurrent)
    item.forceActiveFocus()
    }
    @
    After which stuff works.

    So, is this a bug, maybe already fixed in QtQuick2, or am I missing something?



  • FocusScope documentation is rather flawed. We are adding some new simplified focus policies when we introduce the Qt Quick Controls. I would like tor relay this comment that I found hidden away as a comment on Gerrit, by Andrew Den Exter as I think it adds some vital clues that the official docs dont mention:

    "I think focus scopes need to be explained a bit better, a FocusScope is a container which isolates its descendants from focus changes outside of the scope, and isolates items outside of the scope from internal focus changes. If for example you give active focus to a sibling of a scope that contains the active focus item; focus is removed from the scope but the (non-active) focus state of all items within the scope is unchanged and if you restore focus to the scope then the previous active focus item will be restored. It also works the other way around; a scope without focus can change its internal focus state at any time so that when it does gain active focus the correct child becomes the active focus item.
    The important thing to note from that is that just because an item is a FocusScope doesn't mean it can receive keyboard input, just that it may have a child or children that can and its those children that the focus chain will need to connect."



  • I dont think your isCurrent and focus lines are appropriate. Perhaps you should just set focus:true on the focusable children and let the FocusScope the focus being exclusive, which is its main purpose. Using forceActiveFocus is something I frequently end up doing myself and I don't see any big issues with that.



  • That makes a lot of sense and indeed things fall into place a bit more, thanks Jens!


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.