找回密码
 立即注册
收起左侧

第3篇 Qt Quick入门教程之基础(三)QML语法1

15
回复
44567
查看
[复制链接]
累计签到:1564 天
连续签到:1 天
来源: Qt教程 2019-2-27 22:04:26 显示全部楼层 |阅读模式


导语

前面两篇我们已经成功创建了Qt Quick项目,并搭载好了Android开发环境。俗话说万事开头难,大家可能没感觉到自己已经把最难的地方完成了。接下来就要正式开始探索炫酷的Qt Quick世界了,不过,在这之前,还是需要学习一下Qt Quick世界的相关规则,不然,后面遇到各种问题,会严重影响我们探索的效率和心情!

Qt Quick世界的规则,也可以说是QML语法。说到规则,大家一定会感到很枯燥,一定要学吗?如果哪位同学现在已经考过了驾照,那些条款制度现在还能记住几条?其实,我们不需要完全记住哪条交通规则要扣多少分罚多少款,这个可以到需要的时候再去查,我们只要记住哪些行为是不对的,这就够了。学习语言语法也类似,不要一开始就把什么都死记背过,这个作用不大,能记住有哪些规则或概念就够了,到真正碰到的时候可以再回头来学。等后面用的多了,自然就熟记于心了!

下面,我们开始,尽量让大家不会太枯燥!

语法基础

我们新建空的Qt Quick项目helloqml,下面更改一下自动生成的main.qml文件:

// 下面是导入语句
import QtQuick 2.9
import QtQuick.Window 2.2

/* QML文档可以看做是一个QML对象树,这里创建了Window根对象
和它的子对象Text */
Window {
    visible: true
    width: 640
    height: 480
    title: qsTr("Hello World")

    Text {
        id: text1
        text: qsTr("hello QML!")
    }
}

1. 导入语句

类似于C++中的 include,在QMl中使用 import 语句导入模块,模块中包含了各种QML类型。QtQuick 模块为创建图形用户界面提供了最基本的类型,比如代码中使用的Text类型就包含在 QtQuick 模块中,QML文档中首先要导入该模块。这里我们导入了 QtQuick 2.9,其实在Qt 5.12中最新的QtQuick模块版本是2.12,使用2.9只是为了向下兼容,如果这里直接使用 QtQuick 2.12,那么使用低于 Qt 5.12 的 Qt 版本编译该源码会报错。关于 QtQuick 模块会在后面的教程中详细讲解。

因为代码中使用了 Window 类型,所以这里还导入了 QtQuick.Window 模块。Window类型可以为 Qt Quick 场景创建一个顶级窗口,所以它一般作为根对象,在其中可以创建其他QML对象。

2. QML类型(QML Types)

QML的类型系统包含了基本类型、 QML 对象类型和 JavaScript 类型,这些类型组成了整个QML文档。

  • 基本类型

在QML中将指向简单数据的类型称为基本类型,比如 int 或 string 等。基本类型的概念是相对于QML对象类型而言的,QML 对象类型可以包含属性、信号和函数等,但基本类型不能作为对象,比如 int {} 是不允许的。在QML中原生支持的基本类型如下图所示。

QML模块也可以提供基本类型,例如 date、point、rect、size 等。详细内容大家可以在帮助中索引 QML Basic Types 关键字。

  • QML对象类型(QML Object Types)

QML对象类型就是可以实例化QML对象的类型。从语法上面来说,QML对象类型可以通过类型名称{对象特性} 的格式来定义一个对象。例如,代码中 Window 和 Text 都是对象类型。当对象类型被实例化以后,就被叫做该对象类型的对象 ,例如 Text 对象类型在代码中被实例化为了 Text 类型的对象 Text,之所以这两个概念容易被混淆,是因为它们是同名的。只需要记住对象类型后面添加 {} 后就被称为对象 ,大家也可以类比C++中的类与实例化。

  • JavaScript 类型

QML支持JavaScript对象和数组,可以通过var 类型创建并存储任何标准的JavaScript类型。下面是一个例子:

import QtQuick 2.0

Item {
    property var theArray: []
    property var theDate: new Date()

    Component.onCompleted: {
        for (var i = 0; i < 10; i++)
            theArray.push("Item " + i)
        console.log("There are", theArray.length, "items in the array")
        console.log("The time is", theDate.toUTCString())
    }
}

3. 对象

在前面对象类型处已经讲明了什么是对象,这里再重申一下。QML对象由类型指定,一般与类型同名,名称以大写字母开头,后面跟一对大括号,在括号中包含了对象特性(QML Object Attributes)定义,包括 id、属性、信号、信号处理器、方法、附加属性和附加信号处理器等,当然也可以包含子对象。例如,前面代码中 Window 对象中包含了visible、width、height、title等属性定义和 Text 子对象。

4. 属性(Property)

属性是对象的特性之一,可以分配一个静态的值或者绑定一个动态表达式,属性和值由一个冒号隔开,使用“属性 : 值”语法进行初始化,比如前面代码中width: 640 。属性可以分行写,这样结尾可以不用分号,也可以写在一行,中间使用分号隔开,例如:width: 640 ; height: 480 。可以在任意对象类型的帮助文档中查看该类型的所有属性。

  • id 特性

一个对象一般都会在开始指定一个id,可以通过它在其他对象中识别并引用该对象,id 特性是QML语言本身提供的,不能被QML对象类型进行重定义或者重写。id 值必须使用小写字母或者下划线开头,并且不能使用字母、数字和下划线以外的字符,其值在一个组件的作用域中必须是唯一的。

id 看起来像是一个属性,但 id 特性并不是一个属性。例如前面代码中Text 对象的 id 为 text1,所以可以在其他对象中通过 text1.text 来获取 Text 对象中的 text 属性的值, 但无法通过text1.id 来获取 id 的值。

5. 注释

QML中的注释与C++相似,单行注释使用 “ // ” 开始,直到行末结束;多行注释使用 “ / ” 开始,以 “ / ” 结尾。

更进一步

编译运行程序,可以看到hello QML! 文本显示在窗口左上角。下面更改 Text 对象定义代码如下:

Text {
    id: text1
    text: qsTr("hello QML!")
    anchors.centerIn: parent
}

现在再次编译运行程序,可以看到文本显示到了界面中间。接下来在 Window 根对象中,Text 对象定义的下面继续添加一个 Rectangle 对象定义:

Rectangle {
    id: colorRect
    width: 20 * 2
    height: width
    radius: 20
    color: "green"

    anchors.left: text1.right
    anchors.leftMargin: 10
    anchors.verticalCenter: text1.verticalCenter

    MouseArea {
        anchors.fill: parent
        onClicked: {
            console.debug("colorRect: ", parent.color)
        }
    }
}

Rectangle 也是 QtQuick 模块中一个很常用的对象类型,使用它可以定义一个矩形,这里设置了矩形的宽、高为40,半径radius为20,颜色为绿色,它最终显示效果是一个绿色圆形。运行程序,效果如下图所示。

1. 锚布局

前面使用的 anchors 翻译过来就是锚,使用它可以进行简单的布局,当然这只是QML布局中的一种方法,不过很常用。anchors可以在一个部件的上、下、左、右、水平居中、垂直居中、中心等位置进行锚定,如下图所示。

比如Text 对象中 anchors.centerIn: parent 就是将 Text 对象锚定在了其父对象也就是 Window 的中心。在 Rectangle 对象中,我们使用anchors.left: text1.right 将绿色圆形的左侧与文本的右侧进行锚定,效果就是绿色圆形紧挨文本右侧放置;anchors.leftMargin: 10 表明绿色圆形左侧的边距为10;anchors.verticalCenter: text1.verticalCenter 表明绿色圆形的垂直居中位置锚定到文本的垂直居中位置,效果就是绿色圆形与文本在同一行上,且中心线对其。

2. JavaScript表达式和属性绑定

在Rectangle对象中width属性的值使用了表达式 width: 20 * 2 。在表达式中也可以包含其他对象或属性的引用,例如,height: width ,这也被称作属性绑定,当 width 的值改变时,height 属性的值会跟随变化。

3.进行交互

在QML中一个很常见的设置交互的方式是使用MouseArea,MouseArea本身是不可见的,但是它可以为一些可见内容提供鼠标交互,比如这里,MouseArea对象中 anchors.fill: parent 表明让MouseArea填充整个父对象,这里就是绿色圆形,所以我们可以使用鼠标点击绿色圆形的任何部位来进行交互。当鼠标点击后,就可以在MouseArea中使用 onClicked:{} 来执行想要进行的操作。

4.调试输出

在QML中一般使用console将需要的信息输出到控制台,可用的有console.log, console.debug, console.info, console.warn 和 console.error,比如这里使用了console.debug("colorRect: ", parent.color) ,可以顺序输出参数中的内容,可以是字符串,也可以是对象属性引用。

结语

虽然这一篇是最基础的语法,但是依然包含了众多新的术语、概念、名词,对于新的东西,唯有多用多尝试才能快速掌握。下一篇咱们继续对程序进行扩展,会涉及更多新的内容。




返回目录

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?立即注册

x
参与人数 8人气 +15 收起 理由
deepin-ice + 2 对我帮助很大!
jermy_z + 2 很实用!
thewarrior + 2 对我帮助很大!
liuyuananfang + 1
beiyidan + 2
nxc2018 + 2 很详细!
duliningmissyou + 2
魂之恋歌 + 2 对我帮助很大!

查看全部评分总评分 : 人气 +15

回复

使用道具 举报

累计签到:148 天
连续签到:1 天
2019-2-28 16:12:14 显示全部楼层
跟着教程边学边操作,谢谢霍老师
回复 支持 反对

使用道具 举报

尚未签到

2019-3-10 09:47:46 显示全部楼层
谢谢,获益良多。。。。。。。。。。。。。。。。。。
回复 支持 反对

使用道具 举报

累计签到:319 天
连续签到:1 天
2019-3-21 13:35:54 显示全部楼层
console.debug("colorRect: ", parent.color)     这个是不是应该为 console.debug("colorRect:", colorRect.color);

点评

也可以。  详情 回复 发表于 2019-3-21 18:32
回复 支持 反对

使用道具 举报

累计签到:1564 天
连续签到:1 天
2019-3-21 18:32:50 显示全部楼层
张飞Dear 发表于 2019-3-21 13:35
console.debug("colorRect: ", parent.color)     这个是不是应该为 console.debug("colorRect:", colorRec ...

也可以。
回复 支持 反对

使用道具 举报

累计签到:3 天
连续签到:1 天
2019-3-26 10:19:25 显示全部楼层
简单易懂,非常好理解
回复 支持 反对

使用道具 举报

尚未签到

2019-4-13 11:27:12 显示全部楼层
本帖最后由 千载不变 于 2019-4-13 11:31 编辑

这里有一点没明白 colorRect的父对象应该是window吧,那么parent.color难道不是父对象的颜色?而colorRect的颜色为绿色,但是我按照教程打印出来的调试信息,表明颜色是一样的?霍老师,能否解释一下呢?
再请教一个问题,霍老师 预计什么时候可以出一本QML的书?买了您几本书,很有收获,现在想学习一下QML,但是目前资源比较少
了解了,MouseArea定义在Rectangle中,就是属于Rectangle的对象,我以为MouseArea是属于Rectangle的一个事件...

点评

Qt 5编程入门第2版快要出了,全是讲qml内容的。  详情 回复 发表于 2019-4-14 21:04
回复 支持 反对

使用道具 举报

累计签到:1564 天
连续签到:1 天
2019-4-14 21:04:13 显示全部楼层
千载不变 发表于 2019-4-13 11:27
这里有一点没明白 colorRect的父对象应该是window吧,那么parent.color难道不是父对象的颜色?而colorRect的 ...

Qt 5编程入门第2版快要出了,全是讲qml内容的。
回复 支持 反对

使用道具 举报

尚未签到

2019-4-15 10:02:01 显示全部楼层
yafeilinux 发表于 2019-4-14 21:04
Qt 5编程入门第2版快要出了,全是讲qml内容的。

期待您的新书

您预计这本书,大概什么时候可以面市呢?

点评

得三四个月,关注公众号吧,到时候有通知  详情 回复 发表于 2019-4-15 15:46
回复 支持 反对

使用道具 举报

累计签到:1564 天
连续签到:1 天
2019-4-15 15:46:46 显示全部楼层
千载不变 发表于 2019-4-15 10:02
期待您的新书

您预计这本书,大概什么时候可以面市呢?

得三四个月,关注公众号吧,到时候有通知
回复 支持 反对

使用道具 举报

累计签到:79 天
连续签到:1 天
2019-6-24 21:32:52 显示全部楼层
很好,谢谢!但是好像会报qml: colorRect : undefined错误
回复 支持 反对

使用道具 举报

累计签到:165 天
连续签到:1 天
2020-4-23 16:23:54 显示全部楼层
第五点,注释那里的多行注释写的有点问题
回复 支持 反对

使用道具 举报

累计签到:27 天
连续签到:1 天
2021-5-27 14:56:33 显示全部楼层
文字显示到图标里好看点
  1. import QtQuick 2.12
  2. import QtQuick.Window 2.12
  3. Window {
  4.     width: 640
  5.     height: 480
  6.     visible: true
  7.     title: qsTr("Hello World")
  8.     Rectangle {
  9.         id: colorRect
  10.         width: 20 * 2
  11.         height: width
  12.         radius: 20
  13.         color: "green"
  14.             Text {
  15.                 id: text1
  16.                 text: qsTr("A")

  17.                 anchors.centerIn: parent

  18.             }

  19.        anchors.centerIn: parent

  20.         MouseArea {
  21.             anchors.fill: parent
  22.             onClicked: {
  23.                 console.debug("colorRect: ", parent.color)
  24.             }
  25.         }
  26.     }
  27. }
复制代码

回复 支持 反对

使用道具 举报

累计签到:10 天
连续签到:2 天
2022-8-24 15:49:47 显示全部楼层
请问在哪里下载代码呢
回复 支持 反对

使用道具 举报

累计签到:10 天
连续签到:2 天
2022-8-24 15:54:57 显示全部楼层
Joseph 发表于 2022-8-24 15:49
请问在哪里下载代码呢

自问自答 在第四篇结尾处下载
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

公告
可以关注我们的微信公众号yafeilinux_friends获取最新动态,或者加入QQ会员群进行交流:190741849、186601429(已满) 我知道了