Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

How to keep focus in TextField when reparenting?



  • How can I get my TextField to keep its focus when I reparent it? Using Qt 5.12.2.



  • Hi @Vadi2 , you can use forecActiveFocus() i guess.

    Here is the sample code based on what i have understood,just copy paste the code and check once whether this is what you need:-

     Rectangle {
            width: 500; height: 500
            color: "transparent"
            border.color: "red"
    
            TextField {
                id: txtField
    
                placeholderText: qsTr("Enter Your Name")
                width: 100
                x: blueRect.width
    
                states: State {
                    name: "reparented"
                    ParentChange { target: txtField; parent: redRect;x:0;y:20}
                }
            }
    
            Rectangle {
                id: redRect
    
                width: 100; height: 100
                color: "red"
                anchors.centerIn: parent
            }
    
            //####Click on this rectangle to reparent the textfield
            Rectangle {
                id: blueRect
    
                width: 50; height: 50
                color: "blue"
    
                MouseArea {
                    anchors.fill: parent;
                    onClicked: {
                        txtField.state = "reparented"
                        txtField.forceActiveFocus()
                    }
                }
            }
        }
    

    In this sample code, there is a blue rectangle if you click on it, the TextField will get reparented to a red rectangle and the focus moves to the TextField and you can type in it.



  • I played around with forceActiveFocus() - the difficulty I had is that my reparenting change happens on a when condition:

    states: [
        State {
            name: "MINIMAL"; when: !dotnet.resourceText
            ParentChange {
                target: textArea
                parent: loadResourcesRow
                width: 300
                height: undefined
            }
        },
        State {
            name: "EXPANDED"; when: dotnet.resourceText
            ParentChange {
                target: textArea
                parent: addResourceScrollView
                x: 0; y: 0
                width: addResourcesPage.width
                height: addResourcesPage.height
            }
        }
    ]
    state: "MINIMAL"
    
    transitions: Transition {
        ParentAnimation {
            NumberAnimation { properties: "x,y,width,height";  easing.type: Easing.InCubic; duration: 600 }
        }
    }
    

    In this case it's not possible to call forceActiveFocus() easily, is there?



  • Hi @Vadi2 , ohh okay.

    From your code what i quickly see is the width of the TextField is different in both the states, so is it possible for you to use the "onWidthChanged" signal.

    onWidthChanged: {
                    console.log("On Width Changed")
                    txtField.forceActiveFocus()
                }
    

    Else you can do one more thing, you can use a string and assign it the state of the TextField and after that you can use the onChanged signal.

    property string tempState: txtField.state
    
                onTempStateChanged: {
                    console.log("State Changed",tempState)
                    txtField.forceActiveFocus()
                }


  • Thanks, a combination of:

    // ensure focus remains when the area is reparented
    onWidthChanged: textArea.forceActiveFocus()
    // it doesn't have focus on startup
    Component.onCompleted: textArea.focus = false
    

    Worked!


Log in to reply