概述
Qt QML
模块为使用QML语言开发应用程序和库提供了一个框架。它定义并实现了语言和引擎基础结构,并提供了一个API,使应用程序开发人员能够使用自定义类型扩展QML语言,并将QML代码与JavaScript和c++集成在一起。Qt QML模块提供了QML API和c++ API。
请注意,虽然Qt QML模块为QML应用程序提供了语言和基础结构,但Qt Quick模块提供了许多可视化组件、模型-视图支持、动画框架以及用于构建用户界面的更多内容。
上面这句话是啥意思呢?QML和Quick就类似于C++与C++标准库的关系。没有C++标准库,C++也能进行开发把,但有了标准库,就如虎添翼,不用自己造轮子了。
QML文件
生成.qml文件后,类似于下方代码:
import QtQuick 2.2
import QtQuick.Window 2.2
Window {
visible: true
width: 640
height: 480
title: qsTr("Hello World")
}
以上代码解释如下:
import QtQuick 2.2
:
- 这行代码导入了
QtQuick
模块的版本 2.2。QtQuick
模块包含了创建动画、图形和界面元素所需的所有功能。
import QtQuick.Window 2.2
:
- 这行代码导入了
QtQuick.Window
模块的版本 2.2。QtQuick.Window
模块提供了创建窗口和管理窗口状态的功能。
Window {
:
- 这行代码开始定义一个窗口对象。在 Qt Quick 中,你可以使用
Window
元素来创建一个窗口,并设置其属性。
visible: true
:
- 这行代码设置窗口的可见性为
true
,这意味着当应用程序启动时,窗口将自动显示。
width: 640
:
- 这行代码设置窗口的宽度为 640 像素。
height: 480
:
- 这行代码设置窗口的高度为 480 像素。
title: qsTr("Hello World")
:
- 这行代码设置窗口的标题为 “Hello World”。
qsTr
是一个函数,用于国际化和本地化字符串。在此情况下,它确保标题 “Hello World” 能够根据用户的语言环境正确地显示。
}
:
- 这行代码结束了
Window
对象的定义。
但问题来了,你进行import QtQuick xx
导入的时候,你怎么就知道当前Qt版本对应的QtQuick模块是哪个版本呢?
大概就是Qt 4版本对应的是1.x, Qt 5版本对应的是2.x;如果运行报如下错:
module "QtQuick" version 2.7 is not installed
可以手动改,比如将2.7改为2.6,如果2.6不行就改为2.5;Qt 6版本后好像不用输入Quick版本号了,编译的时候,会自动获取。
以下是一个参考,Qt库版本对应的Qml和Quick模块版本。
QML类型系统
在QML文档中对象层次结构的定义中可能使用的类型可以来自各种来源。它们可能是:
- 由QML语言原生提供
- 通过QML模块通过c++注册
- 由QML模块作为QML文档提供
此外,应用程序开发人员可以通过直接注册c++类型,或者通过在QML文档中定义可重用的组件(然后可以导入)来提供自己的类型。
无论类型定义来自何处,引擎都将为这些类型的属性和实例强制类型安全。
QML基本类型
QML语言内置了对各种基本类型的支持,包括整数、双精度浮点数、字符串和布尔值。对象可以具有这些类型的属性,这些类型的值可以作为参数传递给对象的方法。
QML支持许多基本类型。
QML语言提供的基本类型
QML语言原生支持的基本类型如下:
QML模块提供的基本类型
QML模块可以用更基本的类型扩展QML语言。例如,QtQuick模块提供的基本类型如下:
Qt全局对象为操作基本类型的值提供了有用的函数。
目前只有Qt提供的QML模块可以提供自己的基本类型,但这可能会在Qt QML的未来版本中改变。为了使用特定QML模块提供的类型,客户端必须在其QML文档中导入该模块。
基本类型是指引用简单值的类型,例如int或string。这与QML对象类型形成对比,后者引用具有属性、信号、方法等的对象。
与对象类型不同,基本类型不能用于声明QML对象:例如,不能声明int{}
对象或size{}
对象。
基本类型可以用来指:
- 单个值(例如,int指单个数字,var指单个项目列表)
- 一个包含一组简单的属性值对的值(例如,
size
指的是一个带有width和height属性的值)
单个值示例
int类型指的是整数,例如0、10或-20。
可能的int值范围从-2000000000到2000000000左右,尽管大多数类型只接受一个缩小的范围。
例子:
Item { width: 100; height: 200 }
这种基本类型由QML语言提供。
var
类型示例
泛型属性类型。
var类型是一个泛型属性类型,可以引用任何数据类型。
它相当于一个普通的JavaScript变量。例如,var属性可以存储数字、字符串、对象、数组和函数:
Item {
property var aNumber: 100
property var aBool: false
property var aString: "Hello world!"
property var anotherString: String("#FF008800")
property var aColor: Qt.rgba(0.2, 0.3, 0.4, 0.5)
property var aRect: Qt.rect(10, 10, 10, 10)
property var aPoint: Qt.point(10, 10)
property var aSize: Qt.size(10, 10)
property var aVector3d: Qt.vector3d(100, 100, 100)
property var anArray: [1, 2, 3, "four", "five", (function() { return "six"; })]
property var anObject: { "foo": 10, "bar": 20 }
property var aFunction: (function() { return "one"; })
}
或者:
Item {
property var wheels: 4
Text {
text: "The car has " + parent.wheels + " wheels";
}
}
size类型
具有宽度和高度属性的值
size类型指的是一个具有宽度和高度属性的值。
例如,要读取Image::sourceSize size-type属性的宽度和高度值:
Column {
Image { id: image; source: "logo.png" }
Text { text: image.sourceSize.width + "," + image.sourceSize.height }
}
要创建一个size值,将其指定为"width x height"字符串:
Image { sourceSize: "150x50" }
或者使用Qt.size()
方法:
Image { sourceSize: Qt.size(150, 50) }
当与c++集成时,请注意,从c++传入QML的任何QSize或QSizeF值都会自动转换为大小值,反之亦然。当size值传递给c++时,它会自动转换为QSizeF值。
引擎支持的类型
引擎默认支持一些基本类型,不需要使用import语句,而其他基本类型则需要客户端导入提供它们的模块。下面列出的所有基本类型都可以用作QML文档中的属性类型,但有以下例外:
- list必须与QML对象类型一起使用
- 枚举不能直接使用,因为枚举必须由已注册的QML对象类型定义
如list类型用法:
import QtQuick 2.2
import QtQuick.Window 2.2
Rectangle {
ListModel {
id: myModel
ListElement {
name: "John"
age: 30
}
ListElement {
name: "Jane"
age: 25
}
}
ListView {
id: listView
anchors.fill: parent
model: myModel
delegate: Item {
Text {
text: name + " " + age
}
width: 100 // 设置文本宽度
height: 50 // 设置文本高度
}
// spacing: 20 // 增加列表项之间的间距
}
}
以上示例代码作用:
- 首先该代码包括一个
Rectangle
元素和一个ListView
元素。Rectangle
是一个容器,可以包含其他的QML元素。ListView
是一个用于显示列表数据的滚动区域 - 定义了一个
ListModel
,它包含了两个ListElement
对象。每个ListElement
对象都有两个属性:name
和age
。这些属性用于存储每个列表项的数据 - 在
ListView
中使用了这个ListModel
作为其模型。这意味着ListView
会使用ListModel
中的数据来创建列表项 - 定义了
ListView
的delegate
属性。delegate
是用于定义每个列表项的外观和行为的元素。在例子中,我们使用了一个Item
元素作为代理,它包含一个Text
元素。Text
元素用于显示每个列表项的数据 - 设置了
Text
元素的text
属性,它将显示列表项的name
和age
属性 - 设置了
width
和height
属性来控制文本的显示区域。这些属性确定了文本的宽度和高度,以防止文本溢出其区域并与其他文本重叠 - 为
ListView
添加了spacing
属性,它用于增加列表项之间的间距。这可以帮助避免文本重叠,因为每个列表项都有一些空间来正确地显示其内容。
显示如下:
基本类型的属性更改行为
一些基本类型有属性:例如,字体类型有pixelSize、family和bold属性。与对象类型的属性不同,基本类型的属性不提供自己的属性更改信号。只能为基本类型属性本身创建属性更改信号处理程序:
Text {
// invalid!
onFont.pixelSizeChanged: doSomething()
// also invalid!
font {
onPixelSizeChanged: doSomething()
}
// but this is ok
onFontChanged: doSomething()
}
但是,请注意,每当基本类型的任何属性发生更改时,以及当属性本身发生更改时,都会发出基本类型的属性更改信号。以下面的代码为例:
Text {
onFontChanged: console.log("font changed")
Text { id: otherText }
focus: true
// changing any of the font attributes, or reassigning the property
// to a different font value, will invoke the onFontChanged handler
Keys.onDigit1Pressed: font.pixelSize += 1
Keys.onDigit2Pressed: font.b = !font.b
Keys.onDigit3Pressed: font = otherText.font
}
相反,对象类型的属性会发出自己的属性更改信号,对象类型属性的属性更改信号处理程序只有在将属性重新分配给不同的对象值时才会调用。
JavaScript类型
JavaScript对象和数组由QML引擎支持。任何标准的JavaScript类型都可以使用泛型var类型创建和存储。
例如,可以使用标准的Date和Array类型,如下所示:
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())
}
}
QML Object类型
QML对象类型是QML对象可以实例化的类型。QML对象类型派生自QtObject,并由QML模块提供。应用程序可以导入这些模块来使用它们提供的对象类型。QtQuick模块提供了在QML中创建用户界面所需的最常见对象类型。
最后,每个QML文档隐式地定义一个QML对象类型,该对象类型可以在其他QML文档中重用。
QML Object类型如下:
以上是QML类型的一些介绍。