Элементы ввода в QML

Добавлено 3 марта 2022 в 15:59

Мы уже использовали MouseArea в качестве элемента ввода от мыши. Далее мы сосредоточимся на вводе с клавиатуры. Начнем с элементов редактирования текста: TextInput и TextEdit.

TextInput

TextInput позволяет пользователю ввести строку текста. Этот элемент поддерживает ограничения ввода, такие как validator, inputMask и echoMode.

// textinput.qml

import QtQuick

Rectangle {
    width: 200
    height: 80
    color: "linen"

    TextInput {
        id: input1
        x: 8; y: 8
        width: 96; height: 20
        focus: true
        text: "Text Input 1"
    }

    TextInput {
        id: input2
        x: 8; y: 36
        width: 96; height: 20
        text: "Text Input 2"
    }
}
TextInput

Пользователь может кликнуть на TextInput, чтобы изменить фокус. Для поддержки переключения фокуса с помощью клавиатуры мы можем использовать присоединенное свойство KeyNavigation.

// textinput2.qml

import QtQuick

Rectangle {
    width: 200
    height: 80
    color: "linen"

    TextInput {
        id: input1
        x: 8; y: 8
        width: 96; height: 20
        focus: true
        text: "Text Input 1"
        KeyNavigation.tab: input2
    }

    TextInput {
        id: input2
        x: 8; y: 36
        width: 96; height: 20
        text: "Text Input 2"
        KeyNavigation.tab: input1
    }
}

Присоединенное свойство KeyNavigation поддерживает предустановку клавиш навигации, в которой идентификатор элемента привязан к переключению фокуса при нажатии заданной клавиши.

Элемент ввода текста не имеет визуального представления, кроме мигающего курсора и введенного текста. Чтобы пользователь мог распознать элемент как элемент ввода, он нуждается в некотором визуальном оформлении; например, простой прямоугольник. При размещении TextInput внутри элемента вам нужно убедиться, что вы экспортируете основные свойства, к которым вы хотите, чтобы другие могли получить доступ.

Поэтому для повторного использования мы перемещаем следующий фрагмент кода в наш собственный компонент под названием TLineEditV1.

// TLineEditV1.qml

import QtQuick

Rectangle {
    width: 96; height: input.height + 8
    color: "lightsteelblue"
    border.color: "gray"

    property alias text: input.text
    property alias input: input

    TextInput {
        id: input
        anchors.fill: parent
        anchors.margins: 4
        focus: true
    }
}

Совет

Если вы хотите полностью экспортировать TextInput, вы можете экспортировать элемент, используя property alias input: input. Первый input – это имя свойства, а второй input – идентификатор элемента.

Теперь давайте перепишем наш пример KeyNavigation с новым компонентом TLineEditV1.

Rectangle {
    ...
    TLineEditV1 {
        id: input1
        ...
    }
    TLineEditV1 {
        id: input2
        ...
    }
}
TLineEditV1

Попробуйте использовать клавишу табуляции для навигации. Вы увидите, что фокус не меняется на input2. Простого использования focus: true недостаточно. Проблема в том, что когда фокус был передан элементу input2, элемент верхнего уровня внутри TlineEditV1 (наш Rectangle) получил фокус и не перенаправил его на TextInput. Чтобы предотвратить это, QML предлагает элемент FocusScope.

FocusScope

Область фокуса объявляет, что последний дочерний элемент с focus: true получает фокус, когда данная область фокуса получает фокус. Таким образом, она перенаправляет фокус последнему дочернему элементу, запросившему фокус. Давайте создадим вторую версию нашего компонента TLineEdit с именем TLineEditV2, используя область фокуса в качестве корневого элемента.

// TLineEditV2.qml

import QtQuick

FocusScope {
    width: 96; height: input.height + 8
    Rectangle {
        anchors.fill: parent
        color: "lightsteelblue"
        border.color: "gray"

    }

    property alias text: input.text
    property alias input: input

    TextInput {
        id: input
        anchors.fill: parent
        anchors.margins: 4
        focus: true
    }
}

Наш пример теперь выглядит так:

Rectangle {
    ...
    TLineEditV2 {
        id: input1
        ...
    }
    TLineEditV2 {
        id: input2
        ...
    }
}

Нажатие клавиши табуляции теперь успешно переключает фокус между двумя этими компонентами, и фокусируется правильный дочерний элемент внутри компонента.

TextEdit

TextEdit очень похож на TextInput, но поддерживает многострочное текстовое поле редактирования. У него нет свойств ограничения текста, так как это зависит от запроса размера отрисовки текста (paintedHeight, paintedWidth). Давайте также создаем наш собственный компонент под названием TTextEdit, чтобы предоставить фон области редактирования и использовать область фокуса для лучшей переадресации фокуса.

// TTextEdit.qml

import QtQuick

FocusScope {
    width: 96; height: 96
    Rectangle {
        anchors.fill: parent
        color: "lightsteelblue"
        border.color: "gray"

    }

    property alias text: input.text
    property alias input: input

    TextEdit {
        id: input
        anchors.fill: parent
        anchors.margins: 4
        focus: true
    }
}

Вы можете использовать его как компонент TLineEdit.

// textedit.qml

import QtQuick

Rectangle {
    width: 136
    height: 120
    color: "linen"

    TTextEdit {
        id: input
        x: 8; y: 8
        width: 120; height: 104
        focus: true
        text: "Text Edit"
    }
}
TTextEdit

Элемент Keys

Прикрепленное свойство Keys позволяет выполнять код на основе нажатий определенных клавиш. Например, чтобы переместить и масштабировать квадрат, мы можем использовать клавиши вверх, вниз, влево и вправо для перемещения элемента, а также клавиши плюс и минус для масштабирования элемента.

// keys.qml

import QtQuick

DarkSquare {
    width: 400; height: 200

    GreenSquare {
        id: square
        x: 8; y: 8
    }
    focus: true
    Keys.onLeftPressed: square.x -= 8
    Keys.onRightPressed: square.x += 8
    Keys.onUpPressed: square.y -= 8
    Keys.onDownPressed: square.y += 8
    Keys.onPressed: {
        switch(event.key) {
            case Qt.Key_Plus:
                square.scale += 0.2
                break;
            case Qt.Key_Minus:
                square.scale -= 0.2
                break;
        }

    }
}
Keys

Теги

GUI / Графический интерфейс пользователяQMLQtQtQuickОбучениеПрограммирование

На сайте работает сервис комментирования DISQUS, который позволяет вам оставлять комментарии на множестве сайтов, имея лишь один аккаунт на Disqus.com.

В случае комментирования в качестве гостя (без регистрации на disqus.com) для публикации комментария требуется время на премодерацию.