2

我有一个两列布局,左列中有一个 ListView。使用左/右键,我可以在应用程序的两个部分之间更改焦点。

左列的活动焦点被委托给 ListView 并从那里直接到它的行之一。

如何检查 ListView 或其中一个孩子是否有焦点?

import QtQuick 1.1

FocusScope {
    width: 960
    height: 540
    id: app
    focus: true

    FocusScope {
        id: leftColumn
        KeyNavigation.right: rightColumn
        anchors.bottom: parent.bottom
        anchors.left: parent.left
        anchors.top: parent.top
        width: 250
        focus: true

        Rectangle {
            id: leftBackgroundColor
            anchors.fill: parent
            color: contactsList.activeFocus ? "red" : "#E6E6E6"

            ListView {
                id: contactsList
                interactive: true
                anchors.fill: parent
                focus: true

                delegate: Text {
                    text: name
                    font.bold: activeFocus
                }
                model: ListModel {
                    ListElement { name: "Simon" }
                    ListElement { name: "Mary" }
                    ListElement { name: "Jack" }
                    ListElement { name: "Frank" }
                }

            }
        }
     }


    FocusScope {
        id: rightColumn
        KeyNavigation.left: leftColumn

        anchors.left: leftColumn.right
        anchors.right: parent.right
        anchors.bottom: parent.bottom
        anchors.top: parent.top
        onFocusChanged: console.log("Right focus changed: " + focus + "/" + activeFocus)

        Rectangle {
            id: rightBackgroundColor
            anchors.fill: parent
            focus: true
            color: activeFocus ? "red" : "#b3b3b3"            
        }
    }
}
4

3 回答 3

3

我想我找到了解决方法:

onActiveFocusChanged: { focusChanged(focus) }

每当活动焦点发生变化时,它都会发出focusChanged信号。使用它,属性绑定(如color: parent.focus ? "red" : "#E6E6E6")也可以工作。

完整的测试代码:

import QtQuick 1.1

FocusScope {
    width: 960
    height: 540
    id: app
    focus: true

    FocusScope {
        id: leftColumn
        KeyNavigation.right: rightColumn
        anchors.bottom: parent.bottom
        anchors.left: parent.left
        anchors.top: parent.top
        width: 250

        onActiveFocusChanged: { focusChanged(focus) }

        Rectangle {
            id: leftBackgroundColor
            anchors.fill: parent
            color: parent.focus ? "red" : "#E6E6E6"

            ListView {
                id: contactsList
                interactive: true
                anchors.fill: parent
                focus: true

                delegate: Text {
                    text: name
                    font.bold: activeFocus
                }
                model: ListModel {
                    ListElement { name: "Simon" }
                    ListElement { name: "Mary" }
                    ListElement { name: "Jack" }
                    ListElement { name: "Frank" }
                }

            }
        }
     }


    FocusScope {
        id: rightColumn
        focus: true
        KeyNavigation.left: leftColumn

        anchors.left: leftColumn.right
        anchors.right: parent.right
        anchors.bottom: parent.bottom
        anchors.top: parent.top

        onActiveFocusChanged: { focusChanged(focus) }

        Rectangle {
            id: rightBackgroundColor
            anchors.fill: parent
            focus: true
            color: activeFocus ? "red" : "#b3b3b3"            
        }
    }
}
于 2013-05-14T16:55:00.773 回答
2

我知道这是一个老问题,但我认为它仍然值得一个适当的解释,因为 QtQuick 2 中仍然使用相同的焦点模型。

如何检查 ListView 或其中一个孩子是否有焦点?

这里的核心问题是您似乎对两个焦点属性的含义有些困惑(这是可以理解的,这有点不明显)。

要查看 FocusScope(或其任何子项)现在是否具有焦点,您需要检查其Item::activeFocus上的属性。这意味着“我或我的一个孩子现在有焦点”,当焦点移动到另一个 FocusScope 时,它​​会从 FocusScope 递归清除。

另一方面,Item::focus是对焦点的请求,而不是有关当前状态的信息,因此您不应将其上的其他值(例如color: foo.focus ? "black" : "red")绑定到它,除非您想检查该项目是否能够获得焦点未来的某个时间点,而不是它现在是否有焦点。

这就解释了为什么你可以拥有Item::focus真实的东西,而它实际上并没有焦点——不是信号丢失,而是你滥用属性来表示它不是的东西。

所以,你想要这样的东西:

Rectangle {
        id: leftBackgroundColor
        anchors.fill: parent
        color: leftColumn.activeFocus ? "red" : "#E6E6E6"
}

...

Rectangle {
    id: rightBackgroundColor
    anchors.fill: parent
    focus: true
    color: rightColumn.activeFocus ? "red" : "#b3b3b3"
}
于 2017-01-12T16:39:29.900 回答
0

您在这段代码中为自己制造麻烦。在任何给定时间只有一个元素可以具有焦点,因此如果您将每个元素的焦点属性设置为 true,则在渲染时哪个元素具有焦点并不是特别清楚(我相信它是最后一个渲染的具有焦点设置的元素)。至于找出哪个元素具有焦点,您不能请求当前的焦点元素。您可以做的是将一个侦听器连接到元素上存在的 onFocusChanged 事件,以在该对象获得/失去焦点时执行操作。一个更好的问题可能是你为什么关心谁有焦点?

于 2013-05-13T20:43:31.830 回答