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

时间:2016-09-02 18:23:10

标签: qt focus qml qt-quick qtquickcontrols

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

组件有两部分:

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

行为描述:

  1. 无焦点:默认状态,操纵器不可见 而且你只能看到内部组件
  2. 专注:当您点击该组件(或尝试拖动它)时,请输入 此状态和操纵器变得可见,但您无法访问 内在的组成部分。禁用按Escape或单击组件外部(转到状态1)
  3. 内焦点:双击组件The Manipulator时 保持可见,你仍然可以调整大小但内心 组件具有主要焦点(例如,现在可以是TextEdit 编辑)。禁用pessing Escape(进入状态2)或单击组件外部(进入状态1)
  4. Example of the Component when the Manipulator area is visible

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

    analogy with folder

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

    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"
        }
    }
    

1 个答案:

答案 0 :(得分:0)

我终于找到了解决方案,因为有人在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"
    }
}