具有多个项目的 StackView 中的键处理

key handling in a StackView with multiple items

我有一个包含两个项目的 StackView。两项都应处理一些键。

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

下面的例子说明了这个问题。当按例如 'A' 时,我看到该键由 layer1 和堆栈视图本身处理,但该键不由 layer0 处理。

请注意,由于 transitionFinished

中的 properties.exitItem.visible = true 语句,将 layer1 推到其顶部后 layer0 仍然可见
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
            }
        }
    }
}

I would assume that, if the currentItem in a StackView does not handle a key, that the key would be forwarded to the lower layers but apparently, this is not the case.

显然根据 Qt Documentation 关键事件传播是这样的:

If the QQuickItem with active focus accepts the key event, propagation stops. Otherwise the event is sent to the Item's parent until the event is accepted, or the root item is reached.

如果我理解正确的话,在你的例子中这两个项目是兄弟姐妹。 Layer1 有焦点,它将在层次结构中向上传播事件,而不是水平或向下传播。此外,那些多个 focus: true 不会有任何影响,因为最后一个获得焦点的项目将获得它,在这种情况下 Component.onCompleted

中的 layer1

解决此问题的一种方法是定义一个新信号,例如

Window {
    id: mainWindow
    ...
    signal keyReceived(int key)

然后在 StackView 中触发事件 Keys.onPressed:

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

终于在您的矩形中捕捉到了新信号:

Component {
    id: layer1
    Rectangle {
        Connections {
            target: mainWindow
            onKeyReceived: console.log("layer1")
        }
    }
}