【问题标题】:QML - How to know if a child has keyboard focusQML - 如何知道孩子是否有键盘焦点
【发布时间】:2013-08-19 21:06:49
【问题描述】:

我想我知道如何使用 FocusScopes 以及如何处理键盘焦点。

但我找不到一个聪明的方法来确定我的一个子项目是否 或他们的或我下面的任何人都有键盘焦点。

FocusScope 的文档说:

当焦点范围接收到活动焦点时,包含的元素与 焦点集(如果有)也获得活动焦点。如果这个元素也是 一个 FocusScope,代理行为继续。两者的焦点范围 并且子焦点项将设置 activeFocus 属性。

因此,FocusScope 会将 activeFocus 设置为 false 当焦点被赋予包含的 FocusScope 时。有没有办法弄清楚是否是这种情况?我如何知道是否至少一个包含的 FocusScope 获得了焦点?

【问题讨论】:

  • 我当然可以编写自己的递归检查 hasFocus() 函数。但也许有更好的方法......

标签: qt focus qml


【解决方案1】:

Focus 是 QtQuick 中的一个链。 这意味着所有祖先 FocusScope 到当前活动的孩子都会获得活动焦点。

FocusScope 用于进行一些更简单的焦点抽象:告诉自定义组件当根对象获得活动焦点时,它必须将其转发给给定的子对象。

在下面的例子中:

import QtQuick 2.0;

Rectangle {
    width: 400;
    height: 200;
    focus: true;

    FocusScope {
        id: scope1;
        anchors {
            top: parent.top;
            left: parent.left;
            right: parent.right;
            bottom: parent.verticalCenter;
        }

        Rectangle {
            id: rect1;
            color: (scope1.activeFocus ? "yellow" : "gray");
            border.width: 1;
            anchors.fill: parent;

            MouseArea {
                anchors.fill: parent;
                onClicked: { scope1.forceActiveFocus (); }
            }
            TextInput {
                id: input1;
                focus: true;
                anchors.centerIn: parent;
            }
        }
    }
    FocusScope {
        id: scope2;
        anchors {
            top: parent.verticalCenter;
            left: parent.left;
            right: parent.right;
            bottom: parent.bottom;
        }

        Rectangle {
            id: rect2;
            color: (scope2.activeFocus ? "yellow" : "gray");
            border.width: 1;
            anchors.fill: parent;

            MouseArea {
                anchors.fill: parent;
                onClicked: { scope2.forceActiveFocus (); }
            }
            TextInput {
                id: input2;
                focus: true;
                anchors.centerIn: parent;
            }
        }
    }
}

...我们想要两个可以有焦点的大区域,并且我们不需要明确地关注内部 TextInput(因为理想情况下它们将位于自定义组件内部,因此无法从外部访问)。

所以当一个区域被点击时,我们将活动焦点赋予父作用域,作用域会自动将其代理给具有 focus:true 标志的子作用域(意味着它想要焦点,而不是它拥有它,这就是为什么我们在每个 TextInput 中都有一个标志)。

需要知道内部输入是否具有活动焦点的项目将改为简单地请求范围是否具有它。他们不必关心是在里面。

如果该范围包含另一个具有焦点的范围:true,则再次转发焦点,直到到达想要获得焦点的最新项目。

【讨论】:

    猜你喜欢
    • 2011-11-18
    • 1970-01-01
    • 1970-01-01
    • 2013-05-08
    • 2011-08-23
    • 1970-01-01
    • 2012-04-18
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多