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

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

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

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

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

目录:

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

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 系统编程

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 211,884评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,347评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,435评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,509评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,611评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,837评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,987评论 3 408
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,730评论 0 267
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,194评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,525评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,664评论 1 340
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,334评论 4 330
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,944评论 3 313
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,764评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,997评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,389评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,554评论 2 349

推荐阅读更多精彩内容