Search code examples
listviewfocusqmlqtquick2textedit

Force focus to TextEdit in ListView


Consider following example.

Rectangle {
    height: 200
    width: 200
    ListView {
        id: lv
        anchors.fill: parent
        model: ListModel {
            ListElement {
                name: "aaa"
            }
            ListElement {
                name: "bbb"
            }
            ListElement {
                name: "ccc"
            }
        }
        delegate: TextEdit {
            id: delegate
            text: name
            width: 200
            height: 100
            activeFocusOnPress: false
            onActiveFocusChanged: {
                if(activeFocus) {
                    font.italic = true;
                } else {
                    font.italic = false;
                }
            }
            MouseArea {
                anchors.fill: parent
                onDoubleClicked : {
                    delegate.focus = true;
                    lv.currentIndex = index;
                }
            }
        }
    }
}

I would like to be able to activate TextEdit by double click. If it's outside of list view it works as expected, but in list view it doe's not work. I guess the problem is that list view is focus scope, but I don't know how to fix it.

Thanks in advance.


Solution

  • You can exploit forceActiveFocus:

    This method sets focus on the item and ensures that all ancestor FocusScope objects in the object hierarchy are also given focus.

    You can either use the overloaded version (without parameters) or the one with a FocusReason. Here is the modified version of your code using the latter. I've also made two small adjustments with an explanatory comment:

    import QtQuick 2.4
    import QtQuick.Window 2.2
    
    Window {
        visible: true
        width: 200
        height: 200
    
        ListView {
            anchors.fill: parent
            model: ListModel {
                ListElement {
                    name: "aaa"
                }
                ListElement {
                    name: "bbb"
                }
                ListElement {
                    name: "ccc"
                }
            }
            delegate: TextEdit {
                text: name
                // In the delegate you can access the ListView via "ListView.view"
                width: ListView.view.width  
                height: 50
                activeFocusOnPress: false
                // directly bind the property to two properties (also saving the brackets)
                onActiveFocusChanged: font.italic = activeFocus
    
                MouseArea {
                    anchors.fill: parent
                    onDoubleClicked : {
                        parent.forceActiveFocus(Qt.MouseFocusReason)
                        parent.ListView.view.currentIndex = index
                    }
                }
            }
        }
    }