Подключите обработчик события к ключевому событию TextField

Предположим, у меня есть 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 ответа

В вашем примере Keys.onPressed это то, что известно как подключенный обработчик сигнала. В отличие от большинства других вещей в 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. Создайте настраиваемый компонент, который расширяет возможности прослушивания событий, опубликованных @MrEricSir.
  2. Используйте свойство объекта (https://doc.qt.io/archives/qt-4.8/qml-keys.html). Недвижимость forwardToотправит все события в указанный список: поэтому, когда срабатывает ключевое событие, все указанные элементы будут генерировать это событие.
      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)
        }
    }

}

Если вы напечатаете 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 если вы печатаете), поэтому, если в фокусе находится другой элемент, события не будут перенаправлены.

Другие вопросы по тегам