#(82):输入元素
前面的章节中,我们看到了作为输入元素的`MouseArea`,用于接收鼠标的输入。下面,我们再来介绍关于键盘输入的两个元素:`TextInput`和`TextEdit`。
`TextInput`是单行的文本输入框,支持验证器、输入掩码和显示模式等。
~~~
import QtQuick 2.0
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"
}
}
~~~
[![](https://box.kancloud.cn/2015-12-29_5682328503cb1.png)](http://files.devbean.net/images/2014/02/qml-input-element.png)
注意,我们这里放置了两个`TextInput`,用户可以通过点击输入框改变焦点。如果我们想支持键盘导航,可以添加`KeyNavigation`附加属性。
~~~
import QtQuick 2.0
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`是一个附加属性。当用户点击了指定的按键时,属性指定的组件就会获得焦点。附加属性类似于普通属性,但是又有所区别。普通的属性隶属于这个类型;附加属性一般用于修饰或补充目标类型。比如这里的`KeyNavigation.tab`并不是`TextInput`的普通属性,仅仅是用来说明`TextInput`的一种特征。附加属性的一般语法是`类型.属性名`,以此为例,类型就是`KeyNavigation`,属性名就是`tab`。
与`QLineEdit`不同,QML 的文本出入组件只有一个闪动的光标和用户输入的文本,没有边框等可视元素。因此,为了能够让用户意识到这是一个可输入元素,通常需要一些可视化修饰,比如绘制一个矩形框。当我们这么做的时候,创建一个完整的组件可能是更好的选择,只是要记得导出所需要的属性,以便外部使用。按照这种思路,我们创建一个组件:
~~~
// LineEdit.qml
import QtQuick 2.0
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`的`text`属性,我们给这个属性声明了一个别名。同时,为了让外界可以访问到内部的`textInput`,我们将这个子组件也暴露出来。不过,从封装的角度而言,将实现细节暴露出去并不是一个好的设计,这要看暴露出来这个子组件的影响究竟有多大。然而这些都是关于设计的问题,需要具体问题具体分析,这里不再赘述。
下面我们可以将前面的例子修改成我们新创建的`LineEdit`组件:
~~~
import QtQuick 2.0
Rectangle {
width: 200
height: 80
color: "linen"
LineEdit {
id: input1
x: 8; y: 8
width: 96; height: 20
focus: true
text: "Text Input 1"
KeyNavigation.tab: input2
}
LineEdit {
id: input2
x: 8; y: 36
width: 96; height: 20
text: "Text Input 2"
KeyNavigation.tab: input1
}
}
~~~
只要将 LineEdit.qml 与 main.qml 放在同一目录下,我们就不需要额外的操作,即可在 main.qml 中直接使用`LineEdit`。运行结果如下:
[![](https://box.kancloud.cn/2015-12-29_568232851012e.png)](http://files.devbean.net/images/2014/03/custom-lineedit.png)
现在再来试试键盘导航。这次无论怎么按键盘,焦点始终不会到`input2`。虽然我们在组件中添加了`focus: true`,可是不起作用。原因是,焦点被`inputText`的父组件`Rectangle`获得,然而,`Rectangle`不会将焦点转发给`inputText`。为了解决这一问题,QML提供了另外一个组件`FocusScope`。
当`FocusScope`接收到焦点时,会将焦点转发给最后一个设置了`focus:true`的子对象。所以,我们可以使用`FocusScope`重写`LineEdit`组件:
~~~
// LineEdit.qml
import QtQuick 2.0
FocusScope {
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`一样正常使用了。
`TextEdit`与`TextInput`非常类似,唯一区别是`TextEdit`是多行的文本编辑组件。与`TextInput`类似,`TextEdit`也没有一个可视化的显示,所以我们也需要自己绘制其显示区域。这些内容与前面代码几乎一样,这里不再赘述。
附加属性`Keys`类似于键盘事件,允许我们相应特定的按键按下事件。例如,我们可以利用方向键控制举行的位置,如下代码所示:
~~~
import QtQuick 2.0
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;
}
}
}
~~~
- (1)序
- (2)Qt 简介
- (3)Hello, world!
- (4)信号槽
- (5)自定义信号槽
- (6)Qt 模块简介
- (7)MainWindow 简介
- (8)添加动作
- (9)资源文件
- (10)对象模型
- (11)布局管理器
- (12)菜单栏、工具栏和状态栏
- (13)对话框简介
- (14)对话框数据传递
- (15)标准对话框 QMessageBox
- (16)深入 Qt5 信号槽新语法
- (17)文件对话框
- (18)事件
- (19)事件的接受与忽略
- (21)事件过滤器
- (22)事件总结
- (23)自定义事件
- (24)Qt 绘制系统简介
- (25)画刷和画笔
- (26)反走样
- (27)渐变
- (28)坐标系统
- (29)绘制设备
- (30)Graphics View Framework
- (31)贪吃蛇游戏(1)
- (32)贪吃蛇游戏(2)
- (33)贪吃蛇游戏(3)
- (34)贪吃蛇游戏(4)
- (35)文件
- (36)二进制文件读写
- (37)文本文件读写
- (38)存储容器
- (39)遍历容器
- (40)隐式数据共享
- (41)model/view 架构
- (42)QListWidget、QTreeWidget 和 QTableWidget
- (43)QStringListModel
- (44)QFileSystemModel
- (45)模型
- (46)视图和委托
- (47)视图选择
- (48)QSortFilterProxyModel
- (49)自定义只读模型
- (50)自定义可编辑模型
- (51)布尔表达式树模型
- (52)使用拖放
- (53)自定义拖放数据
- (54)剪贴板
- (55)数据库操作
- (56)使用模型操作数据库
- (57)可视化显示数据库数据
- (58)编辑数据库外键
- (59)使用流处理 XML
- (60)使用 DOM 处理 XML
- (61)使用 SAX 处理 XML
- (62)保存 XML
- (63)使用 QJson 处理 JSON
- (64)使用 QJsonDocument 处理 JSON
- (65)访问网络(1)
- (66)访问网络(2)
- (67)访问网络(3)
- (68)访问网络(4)
- (69)进程
- (70)进程间通信
- (71)线程简介
- (72)线程和事件循环
- (73)Qt 线程相关类
- (74)线程和 QObject
- (75)线程总结
- (76)QML 和 QtQuick 2
- (77)QML 语法
- (78)QML 基本元素
- (79)QML 组件
- (80)定位器
- (81)元素布局
- (82)输入元素
- (83)Qt Quick Controls
- (84)Repeater
- (85)动态视图
- (86)视图代理
- (87)模型-视图高级技术
- (88)Canvas
- (89)Canvas(续)