Qt 官方示例 | 这几个 QML 版的 Hello World 你学会了吗?

1,236 阅读6分钟

.我是老吴,一枚光荣的嵌入式底层劳动人民。

作为一名 C++ 手残党的我,又来分享 Qt 的学习心得啦。

学习 Qt 的最佳途径是阅读官方的手册和示例,

今天要分享的是 Qt 官方提供的几个 Qt Quick 入门示例。

目录:

`1. 梳理几个入门概念`
`2. 示例1:quick_helloworld`
`3. 示例2:quick_scroll`
`4. 示例3:quick_stack`
`5. 示例4:quick_swipe`
`6. 相关参考`

1. 梳理几个入门概念

Qt 整体框架:

图片

QML 是什么?:

一种用于描述应用程序用户界面的声明式编程语言。

QML is a declarative language that allows user interfaces to be described in terms of their visual components and how they interact and relate with one another.

Qt Quick 是什么?

QML 类型和功能的标准库,包括可视化类型、交互式类型、动画功能、模型和视图,特效等。

Qt Quick is the standard library of types and functionality for QML. It includes visual types, interactive types, animations, models and views, particle effects and shader effects.

简单地理解,Qt Quick 是用于编写 QML 应用的标准库。

本文分享的 4 个 Qt Quick 小程序 (基于 Qt-5.14):

其实就是 Qt Creator 里的 4 个 Qt Quick Application 示例模板,学习这几个 demo 不用写一行代码。

图片

点击查看大图

下面快速地分析一下这 4 个小程序。

OK,Let's go.

2. 示例1:quick_helloworld

该示例演示了如何编写 QML 版的 Hello World。

运行效果:

图片

点击查看大图

源码文件:

`quick_helloworld.pro`
`qml.qrc`
`main.cpp`
`main.qml`

源码分析:

main.cpp:

`int main(int argc, char *argv[])`
`{`
 `QGuiApplication app(argc, argv);`
 `QQmlApplicationEngine engine;`
 `const QUrl url(QStringLiteral("qrc:/main.qml"));`
 `QObject::connect(&engine,`
 `&QQmlApplicationEngine::objectCreated,`
 `&app,` 
 `[url](QObject *obj, const QUrl &objUrl) {`
 `if (!obj && url == objUrl)`
 `QCoreApplication::exit(-1);`
 `},`
 `Qt::QueuedConnection);`
 `engine.load(url);`
 `return app.exec();`
`}`

首先用 QUrl 对象来引用 "main.qml" 这个 QML 文件,

然后用 QQmlApplicationEngine 对象来加载 main.qml。

QML 程序的运行依赖于底层的 QML 引擎,

QQmlApplicationEngine 可以快速地帮我们创建 QML 引擎对象并且加载单个的 QML 文件。

main.qml:

`import QtQuick 2.12`
`import QtQuick.Window 2.12`
`Window {`
 `visible: true`
 `width: 320`
 `height: 240`
 `title: qsTr("es-hacker: QML demo")`
 `Rectangle {`
 `width: parent.width`
 `height: parent.height`
 `color: "Green"`
 `Text {`
 `anchors.centerIn: parent`
 `font.pixelSize: Qt.application.font.pixelSize * 2`
 `text: "Hello, World!"`
 `}`
 `}`
`}`

Qt Quick 提供了基础的界面构建块,例如用于显示一块矩形区域的 Rectangle、用于显示文本的 Text 等。

我们可以将 Window、Rectangel、Text 理解为控件,本质上它们都是对象,类型为 QML object type

在 QML 中声明的对象会在程序运行时显示在界面上,并且它们之间是有层次关系的。

而 visible、width、height 等则是对象的 attribute,

所有的 QML object 类型都有自己的 attribute,在 QML 中通过 attribute 来配置 QML 对象。

共有 7 种类型的 attribute :

  • id attribute

  • property attributes,例如上面的 visible、width

  • signal attributes

  • signal handler attributes

  • method attributes

  • attached properties and attached signal handler attributes

  • enumeration attributes

3. 示例2:quick_scroll

该示例演示了如何通过 ScrollView + ListView 控件实现一个带滚动条的列表清单。

运行效果:

图片

点击查看大图

可以鼠标中键或者拖拉滚动条进行查看。

源码文件:

`quick_scroll.pro`
`qtquickcontrols2.conf`
`qml.qrc`
`main.cpp`
`main.qml`

源码分析:

main.cpp:

和上个例子是一样的,不再分析。

main.qml:

`ApplicationWindow {`
 `visible: true`
 `width: 320`
 `height: 240`
 `title: qsTr("Scroll")`
 `ScrollView {`
 `anchors.fill: parent`
 `ListView {`
 `width: parent.width`
 `model: 20`
 `delegate: ItemDelegate {`
 `text: "Item " + (index + 1)`
 `width: parent.width`
 `}`
 `}`
 `}`
`}`

ApplicationWindow 是一个可以方便添加 menu bar, header 和 footer 的 Window。

图片

点击查看大图

ScrollView 提供了一个能滚动的视图,

ListView 提供了一个列表视图,

model 和 delegate 这两个 attribute 是搭配在一起使用的,model 定义了数据源,delegate 则定义了如何显示数据。

在这个例子里 delegate 的值是一个 ItemDelegate 对象,它会将数据通过 "Item index" 的形式显示出来。

4. 示例3:quick_stack

该示例演示了如何通过 Drawer + StackView 控件以实现导航栏切换界面。

运行效果:

图片

点击查看大图

源码文件:

`quick_stack.pro`
`qtquickcontrols2.conf`
`qml.qrc`
`main.cpp`
`main.qml`
`HomeForm.ui.qml`
`Page1Form.ui.qml`
`Page2Form.ui.qml`

源码分析:

main.qml:

`import QtQuick 2.12`
`import QtQuick.Controls 2.5`
`ApplicationWindow {`
 `id: window`
 `visible: true`
 `width: 320`
 `height: 240`
 `title: qsTr("Stack")`
 `header: ToolBar {`
 `ToolButton { ... }`
 `Label {...}`
 `}`
 `Drawer { ... }`
 `StackView { ... }`
`}`

这里设置了程序的整体布局:

  • ToolBar,用于显示导航按键和当前页面的名称;

  • Drawer,用于选择页面;

  • StackView,用于显示页面的内容;

StackView 的初始化:

`StackView {`
 `id: stackView`
 `initialItem: "HomeForm.ui.qml"`
 `anchors.fill: parent`
`}`

StackView 支持以栈的形式存储多个页面,

StackView.depth 用于记录当前存储的页面个数,

这里我们设置了 StackView 的第一个页面是 HomeForm.ui.qml。

HomeForm.ui.qml 和其他两个 pageXform.ui.qml 都没有实质内容,只是简单的显示一下页面名称。

导航键功能:

`ToolButton {`
 `...`
 `onClicked: {`
 `if (stackView.depth > 1) {`
 `stackView.pop()`
 `} else {`
 `drawer.open()`
 `}`
 `}`
`}`

当点击 header 上的导航键时,如果 stackView.depth > 1 ,意味着当前不是在 home page,则返回 home page。

如果已经在 home page 了,则弹出侧边栏。

侧边栏功能:

`Drawer {`
 `...`
 `Column {`
 
 `ItemDelegate {`
 `text: qsTr("Page 1")`
 `onClicked: {`
 `stackView.push("Page1Form.ui.qml")`
 `drawer.close()`
 `}`
 `}`
 `ItemDelegate {`
 `text: qsTr("Page 2")`
 `onClicked: {`
 `stackView.push("Page2Form.ui.qml")`
 `drawer.close()`
 `}`
 `}`
 `}`
`}`

侧边栏的功能是切换页面,这里首先用 Column 控件进行垂直布局,内部包含的是 2 个 ItemDelegate。

ItemDelegate 其实就是带有委托功能的按键,这里只使用了它的按键功能。

当用户按下 Page 按键时,通过 stackView.push 弹出对应的界面。

5. 示例4:quick_swipe

该示例演示了如何通过 SwipeView 控件以实现滑动切换界面。

运行效果:

图片

点击查看大图

源码文件:

`quick_swipe.pro`
`qtquickcontrols2.conf`
`qml.qrc`
`main.cpp`
`main.qml`
`Page1Form.ui.qml`
`Page2Form.ui.qml`

源码分析:

main.qml:

`import QtQuick 2.12`
`import QtQuick.Controls 2.5`
`ApplicationWindow {`
 `...`
 `SwipeView {`
 `id: swipeView`
 `anchors.fill: parent`
 `currentIndex: tabBar.currentIndex`
 `Page1Form {`
 `}`
 `Page2Form {`
 `}`
 `}`
 `footer: TabBar { ... }`
`}`

SwipeView 是一个支持滑动的控件,可存放多个页面,一次只能显示一个页面,用户可以通过滑动来切换页面。

在我们这个例子里,SwipeView 的页面成员是两个自定义的页面,它们的内容也仅仅是显示一下页面的名称等提示信息。

Page1Form.ui.qml:

`Page {`
 `width: 300`
 `height: 200`
 `header: Label {`
 `text: qsTr("Page 1")`
 `font.pixelSize: Qt.application.font.pixelSize * 2`
 `padding: 10`
 `}`
 `Label {`
 `text: qsTr("You are on Page 1.")`
 `anchors.centerIn: parent`
 `}`
`}`

到此,这 4 个 QML 入门示例就讲解完毕啦。

相关参考

《Qt 官方文档》:

  • QML Applications

  • QML Tutorial

  • QML Object Types

  • QML Object Attributes

  • Model/View Tutorial

  • Model/View Programming

《Qt5 编程入门 (第二版)》

《Qt Creator 快速入门》

思考技术,也思考人生

要学习技术,更要学习如何生活

好书推荐:

《就因為「沒時間」,才什麼都能辦到》

作者:吉田穗波

2004年 取得名古屋大学研究所博士学位,妇产科医师。在工作和家庭多头奔忙的情况下,反而让她因有感于「若要改变现状,只能积极提升自己的程度」,而兴起再进修的念头。从申请入学哈佛,准备考试到录取,只花半年时间!2008 年带着三岁,一岁和一个月大的三个女儿,与丈夫一起前往波士顿,两年取得哈佛学位。

豆瓣评分:8.0,790人评价

图片

点击查看大图

能收获什么?

  • 不一样的时间观念;

  • 实用的时间管理方法;

  • 积极的心理建设;

你和我各有一个苹果,如果我们交换苹果的话,我们还是只有一个苹果。但当你和我各有一个想法,我们交换想法的话,我们就都有两个想法了。

觉得文章对你有价值,不妨 在看 + 分享

推荐阅读:

专辑 | Linux 驱动开发

专辑 | 每天一点 C

专辑 | Linux 系统编程