将事件处理程序连接到TextField键事件

时间:2015-07-02 00:42:44

标签: qt qml qtquick2

假设我有一个TextField控件和一个键事件处理程序:

TextField {
    Keys.onPressed: console.log("key was pressed");
}

但我想要的是从外部连接到TextField键事件,而不修改TextField控件本身。这样的事情:

TextField {
    id: textField
}
Connections {
    target: textField
    Keys.onPressed: console.log("key was pressed");
}

它当然不起作用,但也许有办法做到这一点?

2 个答案:

答案 0 :(得分:2)

在您的示例中,Keys.onPressed就是所谓的attached signal handler。与QML中的大多数其他内容不同,附加信号处理程序(和附加属性)在它们所在的对象之外无效。

幸运的是,有一个简单的解决方法:只需在TextField中添加一个新信号,然后倾听:

TextField {
    id: textField

    // Add a new signal here
    signal keyPressed(var event)

    // Connect the existing signal to our new signal
    Keys.onPressed: keyPressed(event)
}

Connections {
    target: textField
    onKeyPressed: console.log("Key pressed", event.text)
}

答案 1 :(得分:0)

是的,根据您的用例有多种解决方案:

  1. 创建一个自定义组件,用于扩展 TextField 侦听 Keys 事件,如@MrEricSir 发布的那样。
  2. 使用 forwardTo 对象 (https://doc.qt.io/archives/qt-4.8/qml-keys.html) 的属性 Keys。属性 forwardTo 会将所有事件发送到给定的 Item 列表:因此,当触发关键事件时,所有指定的项目将发出该事件。
import QtQuick 2.12
import QtQuick.Controls 2.12
import QtQuick.Window 2.12

Window {
    visible: true
    width: 640
    height: 480
    title: qsTr("Events Sample")

    TextField {
        id: textField
        anchors.centerIn: parent

        // Forward textField's key events to the following list of Items
        Keys.forwardTo: [itemEventsHandler1, itemEventsHandler2]
    }

    Item {
        id: itemEventsHandler1

        Keys.onPressed: {
            console.debug("itemEventsHandler1 | Event key: ", event.key)
        }
    }

    Item {
        id: itemEventsHandler2

        Keys.onPressed: {
            console.debug("itemEventsHandler2 | Event key: ", event.key)
        }
    }

}

如果在 textField 上输入 abc,输出为:

qml: itemEventsHandler1 | Event key:  65
qml: itemEventsHandler2 | Event key:  65
qml: itemEventsHandler1 | Event key:  66
qml: itemEventsHandler2 | Event key:  66
qml: itemEventsHandler1 | Event key:  67
qml: itemEventsHandler2 | Event key:  67

现在假设您的 textField 是之后设置的属性。用这种方式可以达到同样的结果:

// The text field that will be set afterwards
property TextField textField

onTextFieldChanged: {
    // Safety check
    if(textField){
        // Forward textField's key events to the following list of Items
        textField.Keys.forwardTo = [itemEventsHandler1, itemEventsHandler2]
    }
}


Item {
    id: itemEventsHandler1

    Keys.onPressed: {
        console.debug("itemEventsHandler1 | Event key: ", event.key)
    }
}

Item {
    id: itemEventsHandler2

    Keys.onPressed: {
        console.debug("itemEventsHandler2 | Event key: ", event.key)
    }
}

请注意,Keys 事件由处于焦点的 Item 发出(在这种情况下,如果您正在输入,则为 TextField),因此如果另一个项目具有焦点,事件将不会被转发。