Qml 具有多个项目的StackView中的密钥处理

Qml 具有多个项目的StackView中的密钥处理,qml,qtquick2,qtquickcontrols,stackview,Qml,Qtquick2,Qtquickcontrols,Stackview,我有一个StackView,里面有两个项目。这两项都应该处理一些键 我假设,如果StackView中的currentItem不处理密钥,则该密钥将被转发到较低的层,但显然情况并非如此 下面的示例说明了该问题。按eg'A'时,我看到按键由layer1和stackview本身处理,但按键不由layer0处理 请注意,由于transitionFinished import QtQuick 2.0 import QtQuick.Window 2.2 import QtQuick.Controls 1.4

我有一个StackView,里面有两个项目。这两项都应该处理一些键

我假设,如果StackView中的
currentItem
不处理密钥,则该密钥将被转发到较低的层,但显然情况并非如此

下面的示例说明了该问题。按eg'A'时,我看到按键由
layer1
和stackview本身处理,但按键不由
layer0
处理

请注意,由于
transitionFinished

import QtQuick 2.0
import QtQuick.Window 2.2
import QtQuick.Controls 1.4

Window {
    id: mainWindow
    visible: true
    width: 1280
    height: 720
    color: "black"

    Component {
        id: layer0
        Rectangle {
            focus:true
            width:200;height:200;color:"red"
            Keys.onPressed: console.log("layer0")
        }
    }
    Component {
        id: layer1
        Rectangle {
            focus:true
            width:200;height:200;color:"#8000FF00"
            Keys.onPressed: console.log("layer1")
        }
    }

    StackView {
        id: stack
        width: parent.width
        height: parent.height
        focus: true

        Component.onCompleted: {
            stack.push(layer0)
            stack.push(layer1).focus=true
        }

        Keys.onPressed: {
            console.log("StackView.onPressed")
        }

        delegate: StackViewDelegate {
            function transitionFinished(properties)
            {
                properties.exitItem.visible = true
                properties.exitItem.focus = true
            }
        }
    }
}
我假设,如果StackView中的currentItem不处理密钥,则该密钥将被转发到较低的层,但显然情况并非如此

显然,根据关键事件,传播过程如下:

如果具有活动焦点的QQuickItem接受密钥事件,则传播停止。否则,事件将被发送到项的父项,直到事件被接受或到达根项为止

如果我理解正确,在您的示例中,这两项是兄弟项。Layer1具有焦点,它将在层次结构中向上传播事件,而不是水平或向下传播。此外,那些多个
焦点:true
不会有任何效果,因为最后一个接收焦点的项目将得到它,在这种情况下,
组件中的layer1.onCompleted

解决这个问题的一种方法是定义一个新的信号

Window {
    id: mainWindow
    ...
    signal keyReceived(int key)
然后在StackView中,在按键上触发该事件。按下:

    Keys.onPressed: {
        console.log("StackView.onPressed")
        keyReceived(event.key)
    }
最后在你的矩形中捕捉到新的信号:

Component {
    id: layer1
    Rectangle {
        Connections {
            target: mainWindow
            onKeyReceived: console.log("layer1")
        }
    }
}
谢谢你的解释(尤其是父母对兄弟姐妹的部分)!您的建议有两个缺点:我们不能停止传播(尽管我们可以检查event.accepted标志),我们不能保证(我认为)密钥首先由最高层接收。我将看看Keys.forwardTo(lowerLayerItem)方法。