# 输入元素
我们早已使用鼠标输入元素 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
是属性名称,第二个是元素名称。
随后我们用 TLineEditV1
组件重写了 KeyNavigation
实例。
Rectangle {
...
TLineEditV1 {
id: input1
...
}
TLineEditV1 {
id: input2
...
}
}
尝试按下 tab 键触发导航。你会发现焦点并未切换至 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
...
}
}
现在按下 tab 键,能成功地在两个组件间正确切换,内部的子元素也能正确的获得焦点。
# TextEdit
TextEdit
与 TextInput
十分类似,支持多行文本。它没有文本约束属性,因为着依赖于查询文本内容尺寸(contentHeight
,contentWidth
)。我们也创建了名为 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: function (event) {
switch(event.key) {
case Qt.Key_Plus:
square.scale += 0.2
break;
case Qt.Key_Minus:
square.scale -= 0.2
break;
}
}
}