Search code examples
qtfocusqmlqtquick2qtquickcontrols2

How does QML focus propagate?


I am trying to figure out how to properly set focus in my application.

I have a component MyItem.qml, which I want to change its background when any of its children gets focus. I also have a MyDerivedItem.qml that derives from MyItem.qml that also should change the background of the base class if any of its children gets focus.

If I understood the documentation correctly, if a component gets focus the focus property of all its parents in the hierarchy are set to true (or until a FocusScope component is reached).

If this is true, then when I press any of the TextFields in MyItem.qml or MyDerivedItem.qml the myItem.focus property should change to true and the background change its color.

I have tried to make a small example of what I want to do, but it does not behave as I expect.

//main.qml
import QtQuick.Controls 2.0

ApplicationWindow {
    height: 768
    width: 1024
    visible: true

    MyDerivedItem {
        anchors.top: parent.top
        anchors.left: parent.left
        anchors.bottom: parent.bottom
        width: parent.width / 2
    }
    MyDerivedItem {
        anchors.top: parent.top
        anchors.right: parent.right
        anchors.bottom: parent.bottom
        width: parent.width / 2
    }
}

//MyItem.qml
import QtQuick 2.7
import QtQuick.Controls 2.0

Rectangle {
    id: myItem

    default property alias data: column.data

    color: focus ? "red" : "green"

    Column {
        id: column

        TextField {
            placeholderText: "Input Text Here"
        }
    }
}

//MyDerivedItem.qml
import QtQuick 2.7
import QtQuick.Controls 2.0

MyItem {
    id: myDerivedItem

    TextField {
        placeholderText: "Derived Input Text Here"
    }

    TextField {
        placeholderText: "Derived Input Text Here"
    }

    TextField {
        placeholderText: "Derived Input Text Here"
    }

    TextField {
        placeholderText: "Derived Input Text Here"
    }

    //...
}

Solution

  • The solution to my problem was a minor change. Adding FocusScope to MyItem.qml as follows:

    //MyItem.qml
    import QtQuick 2.7
    import QtQuick.Controls 2.0
    
    FocusScope {
        id: focusScope
    
        default property alias data: column.data
    
        Rectangle {
            id: myItem
    
            anchors.fill: parent
            color: focusScope.focus ? "red" : "green"
    
            Column {
                id: column
                anchors.fill: parent
    
                TextField {
                    placeholderText: "Input Text Here"
                }
            }
        }
    }