property用来自定义属性。
什么是属性?面向对象中,类由方法和属性构成。对于从C语言的过来人,更喜欢称之为变量。
之所以说“自定义”,是因为QML语言本身已有默认定义好的属性,这些属性不可以重新定义或者覆盖。比如id属性,每一种 QML 对象类型都只有一个id属性,用来被其他对象识别和引用。
1)方法1
先在C++中使用Q_PROPERTY来定义属性,然后将这个类注册到QML系统中
2)方法2
在QML中直接定义,完整的定义格式如下
[default] [required] [readonly] property
属性名称必须以小写字母开头,并且只能包含字母、数字和下划线。
什么是默认属性?给属性赋值时,不需要指定属性名称,直接将“值”赋值给包含属性的“类”。当然了,默认只能有一个,如果多了,“类”就不知道将“值”赋值给谁了。
例如,在一个对象声明中,如果“值”也是一个对象(子对象),并且没有显示的将一个子对象赋值给某个属性,则这个子对象会被赋值给默认属性。
创建对象实例时必须设置使用required标记的属性。
如果可以静态检测到,违反此规则将导致 QML 应用程序无法启动。
如果是动态实例化的 QML 组件(例如通过Qt.createComponent()),违反此规则会导致警告和空返回值。
只能在初始化时为只读属性分配一个值。只读属性初始化后,无论是通过命令性代码还是其他方式,都无法再为其赋予值。
注意:只读属性不能再设置为默认属性
QML可以通过定义相应的“槽函数”来处理内置信号,定义时,有语法要求
on
其中“Signal”是信号的名称,第一个字母大写。示例如下:
import QtQuick 2.0
Item {
width: 100; height: 100
MouseArea {
anchors.fill: parent
onClicked: {
console.log("Click!")
}
}
}
自定义信号的语法如下:
signal <signalName>[([<type> <parameter name>[, ...]])]
示例如下:
import QtQuick 2.0
Item {
signal clicked
signal hovered()
signal actionPerformed(string action, var actionResult)
}
使用Connections属性来连接信号和槽,在Connections中使用target来标记信号源,使用on“Signal”来处理信号
import QtQuick 2.15
import QtQuick.Controls 2.15
Rectangle {
id: rect
width: 250; height: 250
Button {
id: button
anchors.bottom: parent.bottom
anchors.horizontalCenter: parent.horizontalCenter
text: "Change color!"
}
Connections {
target: button
function onClicked() {
rect.color = Qt.rgba(Math.random(), Math.random(), Math.random(), 1);
}
}
}
当 QML 属性的值发生变化时,会自动发出信号,格式为:
onChanged
示例如下:
import QtQuick 2.15
Rectangle {
id: rect
width: 100; height: 100
TapHandler {
onPressedChanged: console.log("taphandler pressed?", pressed)
}
}
使用signal定义一个信号,使用connect将信号连接到这个信号
import QtQuick 2.15
Rectangle {
id: forwarder
width: 100; height: 100
signal send()
onSend: console.log("Send clicked")
TapHandler {
id: mousearea
anchors.fill: parent
onTapped: console.log("Mouse clicked")
}
Component.onCompleted: {
mousearea.tapped.connect(send)
}
}
信号对象可以使用connect()将信号连接到方法
import QtQuick 2.15
Rectangle {
id: relay
signal messageReceived(string person, string notice)
Component.onCompleted: {
relay.messageReceived.connect(sendToPost)
relay.messageReceived("Tom", "Happy Birthday")
}
function sendToPost(person, notice) {
console.log("Sending to post: " + person + ", " + notice)
}
}