#(83):Qt Quick Controls
自 QML 第一次发布已经过去一年多的时间,但在企业应用领域,QML 一直没有能够占据一定地位。很大一部分原因是,QML 缺少一些在企业应用中亟需的组件,比如按钮、菜单等。虽然移动领域,这些组件已经变得可有可无,但在桌面系统中依然不可或缺。为了解决这一问题,Qt 5.1 发布了 Qt Quick 的一个全新模块:Qt Quick Controls。顾名思义,这个模块提供了大量类似 Qt Widgets 模块那样可重用的组件。本章我们将介绍 Qt Quick Controls,你会发现这个模块与 Qt 组件非常类似。
为了开发基于 Qt Quick Controls 的程序,我们需要创建一个 Qt Quick Application 类型的应用程序,选择组件集的时候注意选择 Qt Quick Controls 即可:
[![](https://box.kancloud.cn/2015-12-29_568232860e1e9.png)](http://files.devbean.net/images/2014/05/qqc-project-type.png)
注意,Qt Creator 给出的是 Qt Quick Controls 1.0,而最新版本的 Qt 5.2 搭载的 Qt Quick Controls 是 1.1。1.1 比 1.0 新增加了一些组件,比如`BusyIndicator`等。所以,如果你发现某个组件找不到,记得更新下 Qt Quick Controls 的版本。
Qt Quick Controls 1.1 提供了多种组件:
| 应用程序窗口 ||--|
| -- || -- |
| 用于描述应用程序的基本窗口属性的组件 |
| ApplicationWindow | 对应`QMainWindow`,提供顶层应用程序窗口 |
| MenuBar | 对应`QMenuBar`,提供窗口顶部横向的菜单栏 |
| StatusBar | 对应`QStatusBar`,提供状态栏 |
| ToolBar | 对应`QToolBar`,提供工具栏,可以添加`ToolButton`和其它组件 |
| Action | 对应`QAction`,提供能够绑定到导航和视图的抽象的用户界面动作 |
| 导航和视图 |
| 方便用户在一个布局中管理和显示其它组件 |
| ScrollView | 对应`QScrollView`,提供滚动视图 |
| SplitView | 对应`QSplitter`,提供可拖动的分割视图布局 |
| StackView | 对应`QStackedWidget`,提供基于栈的层叠布局 |
| TabView | 对应`QTabWidget`,提供带有标签的基于栈的层叠布局 |
| TableView | 对应`QTableWidget`,提供带有滚动条、样式和表头的表格 |
| 控件 |
| 控件用于表现或接受用户输入 |
| BusyIndicator | 提供忙等示意组件 |
| Button | 对应`QPushButton`,提供按钮组件 |
| CheckBox | 对应`QCheckBox`,提供复选框 |
| ComboBox | 对应`QComboBox`,提供下拉框 |
| GroupBox | 对应`QGroupBox`,提供带有标题、边框的容器 |
| Label | 对应`QLabel`,提供标签组件 |
| ProgressBar | 对应`QProgressBar`,提供进度条组件 |
| RadioButton | 对应`QRadioButton`,提供单选按钮 |
| Slider | 对应`QSlider`,提供滑动组件 |
| SpinBox | 对应`QSpinBox`,提供微调组件 |
| Switch | 提供类似单选按钮的开关组件 |
| TextArea | 对应`QTextEdit`,提供能够显示多行文本的富文本编辑框 |
| TextField | 对应`QTextLine`,提供显示单行文本的纯文本编辑框 |
| ToolButton | 对应`QToolButton`,提供在工具栏上显示的工具按钮 |
| ExclusiveGroup | 提供互斥 |
| 菜单 |
| 用于构建菜单的组件 |
| Menu | 对应`QMenu`,提供菜单、子菜单、弹出菜单等 |
| MenuSeparator | 提供菜单分隔符 |
| MenuItem | 提供添加到菜单栏或菜单的菜单项 |
| StatusBar | 对应`QStatusBar`,提供状态栏 |
| ToolBar | 对应`QToolBar`,提供工具栏,可以添加`ToolButton`和其它组件 |
我们尝试实现一个编辑器。这是一个简单的文本编辑器,具有新建、剪切、复制和粘贴等操作。程序运行出来效果如下:
[![](https://box.kancloud.cn/2015-12-29_5682328621fed.png)](http://files.devbean.net/images/2014/05/simpleeditor.png)
整个程序都是在 IDE 帮我们生成的 main.qml 中实现的。首先我们需要添加`import`语句:
~~~
import QtQuick 2.1
import QtQuick.Controls 1.1
~~~
注意我们修改了 IDE 生成的默认语句。整个 QML 文档的根元素是`ApplicationWindow`:
~~~
ApplicationWindow {
title: qsTr("Simple Editor")
width: 640
height: 480
...
}
~~~
`ApplicationWindow`是应用程序的主窗口,类似`QMainWindow`,提供了很多预定义的功能,比如菜单、工具栏等。代码里面的`qsTr()`函数类似`tr()`函数,用于以后的国际化。所有面向用户的文本都应该使用这个函数。
下面向`ApplicationWindow`中添加控件:
~~~
menuBar: MenuBar {
Menu {
title: qsTr("&File")
MenuItem { action: newAction }
MenuItem { action: exitAction }
}
Menu {
title: qsTr("&Edit")
MenuItem { action: cutAction }
MenuItem { action: copyAction }
MenuItem { action: pasteAction }
MenuSeparator {}
MenuItem { action: selectAllAction }
}
}
toolBar: ToolBar {
Row {
anchors.fill: parent
ToolButton { action: newAction }
ToolButton { action: cutAction }
ToolButton { action: copyAction }
ToolButton { action: pasteAction }
}
}
TextArea {
id: textArea
anchors.fill: parent
}
~~~
首先看最后面的`TextArea`,这是整个窗口的主要控件,类似于`setCentralWidget()`函数调用。
`menuBar`和`toolBar`两个属性都是`ApplicationWindow`提供的属性。
`menuBar`是`MenuBar`类型的,所以我们创建一个新的`MenuBar`控件。`MenuBar`具有层次结构,这是通过`Menu`的嵌套实现的。每一个菜单项都是用`MenuItem`实现的;菜单项之间的分隔符则使用`MenuSeparator`控件。这点与 QtWidgets 有所不同。
`toolBar`是`Item`类型的,不过通常都会使用`ToolBar`控件。`ToolBar`默认没有提供布局,因此我们必须给它设置一个布局。这里我们直接添加了一个`Row`,作为横向工具栏的布局。这个工具栏要横向充满父窗口,因此设置锚点为`anchors.fill: parent`。虽然我们设置的是充满整个父窗口,但是工具栏的行为是,如果其中只有一个子元素(比如这里的`Row`),那么工具栏的高度将被设置为这个子元素的`implicitHeight`属性。这对结合布局使用非常有用。事实上,这也是工具栏最常用的方法。工具栏中添加了四个按钮,都是`ToolButton`类型。
每一个`MenuItem`和`ToolButton`都添加了一个`action`属性。下面是这部分代码:
~~~
Action {
id: exitAction
text: qsTr("E&xit")
onTriggered: Qt.quit()
}
Action {
id: newAction
text: qsTr("New")
iconSource: "images/new.png"
onTriggered: {
textArea.text = "";
}
}
Action {
id: cutAction
text: qsTr("Cut")
iconSource: "images/cut.png"
onTriggered: textArea.cut()
}
Action {
id: copyAction
text: qsTr("Copy")
iconSource: "images/copy.png"
onTriggered: textArea.copy()
}
Action {
id: pasteAction
text: qsTr("Paste")
iconSource: "images/paste.png"
onTriggered: textArea.paste()
}
Action {
id: selectAllAction
text: qsTr("Select All")
onTriggered: textArea.selectAll()
}
~~~
`Action`类似`QAction`。这里我们还是使用`qsTr()`函数设置其显示的文本。
使用`iconSource`属性可以指定图标。注意这里的图标只能是位于文件系统中的,不能加载资源文件中的图标(当然,这并不是绝对的。如果我们将整个 QML 文档放在资源文件中,那么就可以直接加载资源文件中的图标。我们会在后面的章节详细介绍这种技术。)。当我们直接类似“images/new.png”这种路径时,注意 QML 是运行时解释的,因此这个路径是相对与 QML 文件的路径。所以这里的图标需要放在与 main.qml 文件同目录下的 images 目录中。
`onTriggered`属性是一种信号处理函数,后面可以添加 JavaScript 语句。如果是多条语句,可以使用大括号,例如`newAction`的`onTriggered`。QML 组件可以发出信号。与 C++ 不同的是,QML 组件的信号并不需要特别的连接语句,而是使用”on信号名字”的形式。比如,`Action`有一个名为`triggered`的信号,则其信号处理函数即为`onTriggered`。事实上,这是最简单的一种信号槽的实现。不过,这种实现的困难在于,同一个信号只能有一个固定名字的信号处理函数。不过,我们也可以使用 connect 连接语句。后面的章节中将详细介绍这一点。
至此,我们的编辑器便实现了。由于全部使用了`TextArea`提供的功能,所以代码很简单。不过,复杂的程序都是这些简单的元素堆积而成,所以,我们现在只是简单介绍,具体的控件使用还要根据文档仔细研究。
附件:[SimpleEditor.zip](http://files.devbean.net/code/SimpleEditor.zip)
- (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(续)