代码之家  ›  专栏  ›  技术社区  ›  Ryou

如何将关键焦点传递给QML中的其他项?

  •  2
  • Ryou  · 技术社区  · 7 年前

    以下是我的QML文件中的代码:

    主要的qml公司

    Rectangle {
        id: window    
        color: "white"; width: 240; height: 150
    
        Column {
            anchors.centerIn: parent; spacing: 15
    
            MyClickableWidget {
                focus: true             //set this MyWidget to receive the focus
                color: "lightblue"
            }
            MyClickableWidget {
                color: "palegreen"
            }
        }    
    }
    

    MyClickableWidget。qml公司

    FocusScope {
        id: scope
        //i try to set true instead of the mouse event
        //focus: true
        //FocusScope needs to bind to visual properties of the children
        property alias color: rectangle.color
        x: rectangle.x; y: rectangle.y
        width: rectangle.width; height: rectangle.height
    
        Rectangle {
            id: rectangle
            anchors.centerIn: parent
            color: "lightsteelblue"; width: 175; height: 25; radius: 10; antialiasing: true
            Text { id: label; anchors.centerIn: parent }
            focus: true
            Keys.onPressed: {
                if (event.key == Qt.Key_A)
                    label.text = 'Key A was pressed'
                else if (event.key == Qt.Key_B)
                    label.text = 'Key B was pressed'
                else if (event.key == Qt.Key_C)
                    label.text = 'Key C was pressed'
            }
        }
        MouseArea { anchors.fill: parent; onClicked: { scope.focus = true } }
    }
    

    关于此代码,我有两个问题:

    第一 已设置第一个组件 focus: true . 然后按键时,它将显示文本。但我不清楚为什么要点击 MyClickableWidget 给它焦点,而另一个小部件失去焦点?click事件是否为组件提供了焦点?如果是,哪个部分将获得焦点( scope rectangle )?

    此外,在我看来,下面显示的行是设置 scope.focus true . 所以,我注释掉这一行,插入一行 focus = true 范围 . 但它不起作用,无法将关键焦点传递给其他项。为什么?

    // MouseArea { anchors.fill: parent; onClicked: { scope.focus = true } }
    

    结果是一样的。我不知道为什么代码需要这一行。

    第二 在焦点范围内,如果子对象具有 焦点:true ,将自动设置所有父级和根级 焦点:true ? 如果不在焦点范围内,结果是否相同?

    1 回复  |  直到 7 年前
        1
  •  3
  •   Yoann Quenach de Quivillic    7 年前

    你为什么需要 FocusScope 首先?如果去掉它,代码可以大大简化。

    重要的是要知道 聚焦镜 , 一次只能有一个项目具有焦点 . 应用程序窗口的行为类似于 聚焦镜 它本身为了简单起见,如果某个项目获得了焦点,则先前具有焦点的项目将自动失去焦点。

    FocusRect。qml公司

    Rectangle {
        width: 175;
        height: 25;
        radius: 10;
    
        Text { id: label; anchors.centerIn: parent }
    
        Keys.onPressed: {
            if (event.key == Qt.Key_A)
                label.text = 'Key A was pressed'
            else if (event.key == Qt.Key_B)
                label.text = 'Key B was pressed'
            else if (event.key == Qt.Key_C)
                label.text = 'Key C was pressed'
        }
    
        MouseArea
        {
            anchors.fill: parent
            onClicked: parent.forceActiveFocus()
        }
    }
    

    主要的qml公司

    ApplicationWindow {
    
        width: 960
        height: 540
    
        Column {
            anchors.centerIn: parent; 
            spacing: 15
    
            FocusRect {
                focus: true             //set this MyWidget to receive the focus
                color: "lightblue"
            }
            FocusRect {
                color: "palegreen"
            }
        }
    }
    

    这里的行为是严格的。项目必须具有activeFocus才能获取关键事件。对于要将activeFocus设置为true的项目,必须满足两个条件

    • 项本身的focus属性设置为true
    • 其最近的FocusScope父级具有activeFocus或没有FocusScope父级,并且应用程序窗口具有active focus。

    在这个简单的示例中,设置 MyClickableWidget 设置为true还将其activeFocus设置为true(无父FocusScope),使其能够获取KeyEvents。

    在回答第二个问题时 聚焦镜 ,将项目的焦点设置为true将不会有任何副作用。但是,强制它获得activeFocus(通过调用 forceActiveFocus() 将使其所有FocusScope父级获得activeFocus(从而将项目父级层次结构中的所有FocusScope的focus设置为true)

    相反,如果焦点镜获得活动焦点,并且有一个子项的焦点设置为true,则子项的活动焦点也将设置为true。