函数
函数格式:
function关键字 函数名(参数名1:参数类型,参数名2:参数类型,...):返回值类型{}
其中:
- 函数名必须以小写字符开头,后面驼峰
- 可以有多个参数或者没有参数
- 参数类型可以不写
- 返回值类型也可以不写
如何调用:通过id点出来
举例:
Rectangle {
id: rect
//显示指定参数类型和返回值类型
function getWidth(num1: int, num2: int): int {
return num1 + num2;
}
//不显示指定
function getHeight(num1, num2) {
return num1 * num2;
}
//调用
width: rect.getWidth(10, 20)
height: rect.getHeight(1, 20)
}
信号
信号格式:
signal关键字 信号名(参数名1:参数类型,参数名2:参数类型...)
其中:
- 信号名仍然要首字母小写,后面驼峰
- 参数可以有多个或没有
- 若有参数则参数类型必须要写
- 同一个作用域内信号名要唯一,不能多个信号重名
举例:
Rectangle {
id: rect2
width: 100
height: 50
color: "red"
//声明1个信号
signal testSignal(num: int)
}
自动绑定信号的槽函数
定义一个信号号,同时可以定义一个自动绑定信号的槽函数
即自己发出信号,自己接收信号然后处理
格式为:
on信号名:(参数列表)=>{}
其中:
- 信号名的首字母要变成大写
- 参数的个数可以少于信号的个数,也可以多于信号的参数
- 参数不能加参数类型,只需要参数名
举例:
Rectangle {
id: rect2
width: 100
height: 50
color: "red"
//声明1个信号
signal testSignal(num: int)
//on+信号名首字母大写
//信号处理函数中打印这个参数
onTestSignal: (num) => {
print(num);
}
//槽函数参数可以没有,也可以多与信号
// onTestSignal:(num1,num2)=>{
// print(num1);
// }
// onTestSignal:{
// //没有参数时,即忽略信号里的参数,不使用
// print("----");
// }
//点击这个矩形,发射信号
MouseArea {
anchors.fill: parent
onClicked: rect2.testSignal(10)
}
}
属性改变信号处理器
自定义一个属性后,qml会自动生成这个属性改变的处理器(槽函数)
同样是自己发出属性改变信号,自己接受信号处理
格式:
on属性名Changed:{}
其中:
- 属性名要变成大写开头
举例:
Rectangle {
id: rect3
width: 100
height: 50
color: "red"
//声明属性num
property int num: 10
//自动生成的属性变化处理器
onNumChanged: {
print("num属性变化了,num:" + rect3.num)
}
//点击后修改这个属性,对应的处理器就会自己调用
MouseArea {
anchors.fill: parent
onClicked: rect3.num++
}
}
connect函数
可以 将自己的信号 连接到 在其他元素中定义的槽函数
即自己发出信号,由其他对象接受信号进行处理
通常会在元素创建完成后Component.onCompleted中,将信号和槽函数进行连接
此方法连接信号和槽,对槽函数的名称没有要求
举例:
Rectangle {
id: rect4
width: 100
height: 50
color: "red"
//定义信号
signal testSignal(w: int)
MouseArea {
anchors.fill: parent
onClicked: rect4.testSignal(rect4.width)
}
//通常在元素创建完成之后将信号与对应的槽函数进行连接
Component.onCompleted: {
//信号调用connect方法连接到其他元素中的槽函数
rect4.testSignal.connect(rect5.doSomething)
}
}
Rectangle {
id: rect5
width: 100
height: 50
color: "yellow"
//定义槽函数
function doSomething(w: int) {
print("4号矩形的宽度是:" + w)
}
}
Connections元素
可以 将其他元素中的信号 与 自己的槽函数进行连接
Connections元素的写法:
Connections {
//需要指定target,即连接谁的信号
target: 某个元素的id
//可以在Connections同时连接多个信号
function on信号名(){}
}
槽函数格式为:
和普通函数一样,只是名称有要求
function关键字 on信号名(参数名1:参数类型,参数名2:参数类型,...):返回值类型
其中:
- 信号名的首字母要变成大写
举例:
Rectangle {
id: rect6
width: 100
height: 50
color: "red"
signal mySignal1(info: string)
signal mySignal2()
//点击发射信号
MouseArea {
anchors.fill: parent
onClicked: {
rect6.mySignal1("你好")
rect6.mySignal2()
}
}
}
Rectangle {
id: rect7
width: 100
height: 50
color: "blue"
//连接rect6中的信号
Connections {
//需要指定target,即连接谁的信号
target: rect6
//可以在Connections同时连接多个信号
//连接rect6中的mySignal1信号
function onMySignal1(info: string) {
print(info)
}
//连接rect6中的mySignal1信号
function onMySignal2() {
print("响应rect2中的mySignal2信号")
}
}
}
注意connect函数和Connections元素的区别
- 前者是将自己的信号连接其他元素的槽函数
- 后者是将自己的槽函数连接到其他元素中的信号
基本数据类型
其中:
color,font,rect,point如何赋值:
property color c: "#FF112233" //ARGB,前面两位那个是透明度
property point p: Qt.point(50, 100)
property rect r: Qt.rect(50, 50, 100, 100)
property font f: ({
family: "微软雅黑"
}) //js对象
property font ff: Qt.font({
family: "微软雅黑",
bold: true
})
枚举类型注意点:
- 自定义的qml文件的名称需要首字母大写,定义的枚举无法在当前qml文件中使用和访问
- 当前qml文件中只能使用其他qml文件中定义的枚举
- 枚举名需要首字母大写,枚举值也要首字母大写
- 访问格式:qml文件名.枚举类型名.枚举值
举例:
MyItem.qml文件中定义了枚举Week
Item {
width: 100
height: 100
enum Week{
Mon=1,
Tue=2
}
}
在另一个qml文件中使用
Rectangle{
width:100
height:100
//定义了一个属性,并赋枚举值
property int week:MyItem.Week.Mon
}
其他类型
qml自带的或者自己定义的这些元素类型
Rectangle {
width: 100
height: 100
//定义了一个属性,属性的类型是自己定义的元素
property MyItem myitem: MyItem {
width: 100
}
//定义了一个属性,属性的类型是qml自带的Button
property Button btn: Button {
text: "按钮"
}
}
js对象
Rectangle {
width: 100
height: 100
//js里的日期
property var date: new Date()
}
JS属性绑定
就是属性1可以绑定另一个属性2
但是如果对属性1进行重新赋值后,两者的绑定关系就不在绑定了,应该是修改属性2的值来间接的修改属性1
举例:
高度绑定了宽度,总是高度的一半;鼠标点击后,高度重新赋值为200,就解除绑定,不再是宽度的一半了,修改宽度也不会影响高度了。
Rectangle {
id: rect
width: 200
//属性绑定 可以绑定对象属性,也可以是表达式,还可以是js函数
height: width / 2 //宽度是高度的一半
color: "red"
MouseArea {
anchors.fill: parent
onClicked: {
rect.width += 10
rect.height = 200 //重新给矩形的高度赋值,原来的表达式就解除绑定了,不会再是宽度的一半了,
}
}
}
还有一个问题,两个属性双向绑定后如何赋初值,直接用=号赋值会解除绑定:
通过 在Component.onCompleted 中修改另一个属性的值,这样就不会接触绑定关系,也对属性的值进行了初始化
//r1和r2的颜色属性进行了双向绑定,两者颜色保持一致
Rectangle {
id: r1
width: 100
height: 100
color: r2.color
//在Component.onCompleted中修改r2的颜色,这样既不会解除绑定,也赋了初值
Component.onCompleted: {
r2.color = "red"
}
}
Rectangle {
id: r2
anchors.left: r1.right
anchors.leftMargin: 10
width: 100
height: 100
color: r1.color
}
自定义qml组件
- qml文件名要大写,只能包含字母、数字、下划线,qml文件名自动被qml的引擎解释为自定义的组件名
- 同一目录下的qml文件会自动设置为可用 不需要import
举例:
有一个MyRectangle.qml文件,自定义了一个矩形
暴露内部的属性
Rectangle{
width: 200
height: width
radius: height/2
color:"red"
//使用这个自定义组件时,不能在外部直接设置子元素的属性,
//需要在最外层的父元素中通过自定义属性的方式将子元素的属性暴露出来
property color innerColor: "green"
Rectangle{
id:innerRect
anchors.centerIn: parent
width: parent.width/2
height: innerRect.width
color: parent.innerColor//绑定暴露出去的属性
}
}
使用这个MyRectangle
MyRectangle {
width: 100
innerColor: "lightgreen"//给内部矩形设置颜色
}
代码风格
官方推荐的代码风格是
- id
- 自定义属性
- 信号
- 信号处理器
- js函数
- 元素自带属性,并且相关的属性放在一起
- 子元素
举例:
Rectangle {
id: rect1 //id
property int customPro1: 1 //自定义属性
property int customPro2: 1
signal customSig1() //信号
signal customSig2()
onWidthChanged: {} //信号处理器
onCustomSig1: {}
function myFunc1() {} //js函数
function myFunc2() {}
x: 10 //元素自带的属性
y: 10
width: 100
height: 100
color: "red"
Rectangle { //子元素
}
}