繁体   English   中英

如何在我的自定义QML组件中管理Focus with States?

[英]How to manage Focus with States in my custom QML component?

我创建了一个可拖动的自定义组件,以便管理各个快速控制组件的几何形状。

组件有两部分:

  • “Manipulator”是一个可拖动且可调整大小的Rectangle
  • 内部组件位于操纵器的中心

行为描述:

  1. 无焦点 :默认状态,操纵器是不可见的,您只能看到内部组件
  2. 重点 :当您单击组件(或尝试拖动它)时,您将进入此状态,并且操纵器变为可见但您无法访问内部组件。 禁用按Escape或单击组件外部(进入状态1)
  3. 内焦点 :当您双击组件时,操纵器保持可见,您仍然可以调整大小,但内部组件具有主焦点(例如,TextEdit现在可以编辑)。 禁用pessing Escape(进入状态2)或单击组件外部(进入状态1)

当Manipulator区域可见时,Component的示例

此组件的逻辑类似于桌面环境中文件夹的逻辑(调整大小除外)操纵器将是文件夹本身,内部组件是其名称。

与文件夹类比

在这里,我发布了我的操纵器的简化版本,我确定它将有助于构建答案,(我尝试了几个小时的很多变化,这是那些非功能性尝试之一)

FocusScope{
    id: root
    width: 175; height: 25;
    focus: true

    states: [
        State {
            name: "noFocus"
            when: !manipulator.activeFocus && !innerComp.activeFocus
            PropertyChanges {
                target: innerComp
                enabled: false
            }
            PropertyChanges {
                target: manipulator
                visible: false
            }
        },

        State {
            name: "focused"
            when: manipulator.activeFocus
            PropertyChanges {
                target: innerComp
                enabled: false
            }
            PropertyChanges {
                target: manipulator
                visible: true
            }
        },
        State {
            name: "innerFocus"
            when: innerComp.activeFocus
            PropertyChanges {
                target: innerComp
                enabled: true
            }
            PropertyChanges {
                target: manipulator
                visible: true
            }
        }
    ]

    //visual area of manipulation (drag, redimension, etc)
    MouseArea{
        id: manipulator
        anchors.fill: parent

        onDoubleClicked: forceActiveFocus(innerComp) //go to state 3 "innerFocus"
        drag.target: manipulator

        Keys.onEscapePressed: forceActiveFocus(root) //I don´t think this is the correct to loose focus but I don´t know how to do that

        Rectangle {
            id: background
            anchors.fill: parent
            color: "lightsteelblue";
        }
    }
    //Inner Component (TextField for example)
    InnerComp {
        id: innerComp
        anchors.fill: parent

        Keys.onEscapePressed: forceActiveFocus(manipulator) //return state 2 "focused"
    }
}

我终于找到了解决方案,因为有人在qt论坛中消化:

也许逆转依赖,即使焦点取决于状态,而不是状态取决于焦点?

所以我改变了我的代码,现在它的工作原理!

我在这里发布解决方案给那些可能对它感兴趣的人(正如我所说的这是真实代码的简化版本):

Item {
    id: root
    width: 175; height: 25;

    states: [
        State {
            name: "noFocus"

            PropertyChanges {
                target: innerComp; enabled: false
            }
            PropertyChanges {
                target: background; visible: false
            }
            PropertyChanges {
                target: manipulator; focus: true
            }
        },

        State {
            name: "focused"

            PropertyChanges {
                target: innerComp; enabled: false
            }
            PropertyChanges {
                target: background; visible: true
            }
            PropertyChanges {
                target: manipulator; focus: true
            }
        },
        State {
            name: "innerFocus"

            PropertyChanges {
                target: innerComp; enabled: true
            }
            PropertyChanges {
                target: background; visible: true
            }
            PropertyChanges {
                target: manipulator; focus: true
            }
        }
    ]
    state: "noFocus"

    //visual area of manipulation (drag, redimension, etc)
    MouseArea{
        id: manipulator
        anchors.fill: parent

        onPressed: {
            root.state = "focused"
            forceActiveFocus(manipulator) //this prevents loosing focus in some especific situations
        }
        onDoubleClicked: root.state = "innerFocus"

        Keys.onEscapePressed: root.state = "noFocus"

    }
    Rectangle {
        id: background
        anchors.fill: parent
        color: "lightsteelblue";
    }
    //Inner Component (TextField for example)
    InnerComp {
        id: innerComp
        anchors.fill: parent

        Keys.onEscapePressed: root.state = "focused"
    }
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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