import
跟c++中的头文件一样,qml中也需要,使用的是import进行导入
- 导入模块
import <ModuleIdentifier> [<Version.Number>] [as <Qualifier>]
即:import 库名 主版本号.副版本号 as 标识
其中版本号在qt6之后就不需要了,标识可有可无,加了标识的话,访问里面的元素就需要加上标识
举例
//不加标识
import QtQuick.Controls
Button{
}
----------------------------------------------
import QtQuick.Controls as Con
//加了标识后,访问里面的元素时也需要加上标识.来访问
Con.Button{
}
- 导入同一个文件夹下的qml文件
不需要导入可以直接使用qml文件中定义的元素
- 导入不同文件夹下的qml文件
import "<DirectoryPath>" [as <Qualifier>]
需要指定qml文件所在的文件夹的路径, 但不能指定到具体的文件,否则会提示不存在;标识可加可不加
举例
//当前路径下有一个文件夹test,需要访问里面的qml文件,标识可加可不加
import "./test"
- 导入js文件
import "<JavaScriptFile>" as <Identifier>
需要指定到具体的js文件,标识必须要加
举例
//test文件夹下有一个myjs.js文件 ,需要指定到具体的js文件,将他导入并添加标识
import "./test/myjs.js" as MyJs
//调用里面的函数时需要加加上标识来访问
MyJs.func()
id
- 唯一的
- 只读 的
- 非对象的属性(qml的一种数据类型)
- 小写字母或下划线开头
- 只能包含字母、数字和下划线
- 实际的值是一个大小随机的16进制的数字(可以理解为元素实例对象的地址)
自定义属性
语法格式:[default] [required] [readonly] property <propertyType>[:value]
property关键字 属性类型 属性初始值
其中,default、required、readonly为可选项
属性初始值也可以没有
- default:
默认的,没什么特别意义,可加可不加
- required:
必须的,定义的时候不能赋初值,需要用户在使用包含这个属性的元素时,这个属性必须
要先赋值
还可以将一个已存在的属性转为required
Rectangle {
id: rect
required width//将宽度属性设为必须的
width: 100
}
- readonly:
只读的,即这个属性不可修改,且必须在定义的时候就要赋初值
只读属性不能同时是default
举例
Rectangle{
default property int a1:6 //定义一个属性a1,并赋初值
required property int a2//定义一个必需变量a2,不能赋初值
readonly property int a3: 4//定义一个只读变量a3,定义时就要赋初值
a2:4//需要用户显式地赋初值
}
属性的类型
- 值类型,属性的值通过值传递
即把该属性的值赋值给另一个属性时,被赋值的一方对值的修改不会影响赋值方
以下都是值类型
- 对象类型,属性的值通过引用传递
即把该属性的值赋值给另一个属性时,任何一方对值的修改都会互相影响
以下是对象类型
- C++定义的类型(cpp定义的扩展qml类型的类也可以在qml中使用)
- qml里面的自带的元素,比如
property Item someItem //定义一个类型为Item的属性
property Rectangle someRectangle//定义一个类型为Rectangle的属性
//Item和Rectangle都是qml里面自带的元素
- qml文件定义的类型:qml文件的名称就是类型,且需要大写
- 枚举类型,比如
//MyRectangle.qml文件中定义了一个枚举enum TextType { Normal, Heading }
//另一个文件中使用这个枚举
property int textType: MyRectangle.TextType.Normal
枚举类型和值必须以大写字母开头
- 信号和槽函数属性
- js 函数
信号处理器
属性再被定义之后qml还会隐式的创建一个信号处理器
格式: on<PropertyName>Changed,PropertyName属性名称会自动大写
举例
Rectangle {
property int myWidth: 100
onMyWidthChanged: {
//do something
}
}
定义别名
相当于这个别名和另一个属性建立双向绑定的关系,任何一方改变都会更新对方
被引用的属性需要通过id访问
[default] property alias <name>: <alias reference>
比如
Rectangle {
id: rect
width: 100
//被引用的属性需要通过id访问,否则找不到
property alias myWidth: rect.width
}
- 别名的深度最多2层
正确:property alias color: rectangle.border.color//2层,通过id访问被引用的属性
错误:property alias color: myItem.myRect.border.color//3层
- 只有在组件完全创建之后,别名才会被激活,才能去读写这个别名
定义一个列表类型的属性
- 可以通过length访问这个属性的元素个数
- 通过下标运算符[ ]访问这个属性的元素
//还可以定义一个列表 可以访问长度 nums.length 下标运算符访问元素nums[0]
property list<int> nums: [1,2,3,4]
property list<Rectangle> rts: [
Rectangle{color:"red"},
Rectangle{color:"blue"}
]
属性组
//比如修改字体的相关属性时
Text {
id: txt
text: qsTr("text")
// font.pixelSize: 18
// font.bold: true
//还可以这样写属性组
font{pixelSize: 18;bold: true}
}
附加属性(Attached Properties)
比如ListView的isCurrentItem属性,Component的onCompleted,还有很多
主要的作用就是可以在另一个元素中直接访问这个属性,通过元素名.属性的形式进行访问
有一点C++里面的静态方法的意思,不需要实例对象就可以直接使用和访问
比如
//附加属性和附加属性的信号处理器
//就是使我们能在一些特定时机执行一些代码
Item{
//表示组件创建完成时
Component.onCompleted: {
print("ok");
}
}