Элементы ввода в QML
Мы уже использовали 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
, чтобы изменить фокус. Для поддержки переключения фокуса с помощью клавиатуры мы можем использовать присоединенное свойство 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
...
}
}
Попробуйте использовать клавишу табуляции для навигации. Вы увидите, что фокус не меняется на 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"
}
}
Элемент 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;
}
}
}