简体   繁体   中英

How do multiple child items requesting focus get focus within a FocusScope type?

I'm new to QML and I'm confused by the FocusScope type. My understanding is that it's used to control the focus of part an application when multiple items are requesting focus.

The documentation says:

Conceptually focus scopes are quite simple.

Within each focus scope one element may have Item::focus set to true. If more than one Item has the focus property set, the last element to set the focus will have the focus and the others are unset, similar to when there are no focus scopes.

So, when the program is run, why is the first textfield in the following code focused and not the last?

import QtQuick 2.0
import QtQuick.Controls 2.14
import QtQuick.Layouts 1.15

ApplicationWindow{
    visible: true
    width: 200
    height: 200

    FocusScope{

        Column{
            Text{text: "first focus scope"}
            TextField {
                width: 100; height: 25; focus: true
                text: focus
            }
            TextField{
                width: 100; height: 25; focus: true
                text: focus
            }

            Text{text: "second focus scope"}
            TextField {
                width: 100; height: 25; focus: true
                text: focus
            }
            TextField{
                width: 100; height: 25; focus: true
                text: focus
            }
        }
    }
}

Any help is greatly appreciated!

The order in which properties are set is undefined :

As a general rule, users should not rely on the evaluation order of bindings.

You can see which order they're actually set in with the following code:

import QtQuick 2.0
import QtQuick.Controls 2.14
import QtQuick.Layouts 1.15

ApplicationWindow {
    width: 200
    height: 200
    visible: true

    FocusScope {

        Column {
            Text {
                text: "first focus scope"
            }
            TextField {
                objectName: "textField1"
                width: 100
                height: 25
                text: focus
                focus: {
                    print(objectName, "setting focus to true")
                    true
                }
                onFocusChanged: print(objectName, "focus changed to", focus)
            }
            TextField {
                objectName: "textField2"
                width: 100
                height: 25
                text: focus
                focus: {
                    print(objectName, "setting focus to true")
                    true
                }
                onFocusChanged: print(objectName, "focus changed to", focus)
            }

            Text {
                text: "second focus scope"
            }
            TextField {
                objectName: "textField3"
                width: 100
                height: 25
                text: focus
                focus: {
                    print(objectName, "setting focus to true")
                    true
                }
                onFocusChanged: print(objectName, "focus changed to", focus)
            }
            TextField {
                objectName: "textField4"
                width: 100
                height: 25
                text: focus
                focus: {
                    print(objectName, "setting focus to true")
                    true
                }
                onFocusChanged: print(objectName, "focus changed to", focus)
            }
        }
    }
}

This is the output:

qml: textField4 setting focus to true
qml: textField4 focus changed to true
qml: textField3 setting focus to true
qml: textField4 focus changed to false
qml: textField3 focus changed to true
qml: textField2 setting focus to true
qml: textField3 focus changed to false
qml: textField2 focus changed to true
qml: textField1 setting focus to true
qml: textField2 focus changed to false
qml: textField1 focus changed to true

You can only have one item with active focus at a time, so setting focus to true for more than one sibling doesn't make much sense.

If you want to eg have the first TextField have focus on startup, I'd just do this:

ApplicationWindow {
    // ...
    Component.onCompleted: textField1.forceActiveFocus()

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM