1. 添加函数
QML组件中可以定义JavaScript代码的函数,这些函数可以在内部调用,也可以被其他对象调用。
function <name> ([<parameter name>[,...]]) {<body>}
与信号不同,函数的参数类型不需要声明,它们默认是variant类型。函数体使用JavaScript进行编写,在其中可以访问参数。
import QtQuick 2.4
Rectangle {
id: rect
width: 240; height: 320
function say(text) {
console.log("You said: " + text);
}
MouseArea {
anchors.fill: parent
onClicked: rect.say("Mouse clicked") //函数与信号关联
}
}
2. 添加信号
当一个事件发生时,可以使用洗好通知其他对象。例如,MouseArea的clicked信号通知其他对象在这个区域已经单击过了。定义一个新信号的语法:
signal <name> [([<type><parameter name>[,...]])]
同一个类型块中不能声明两个相同名称的信号。
Item {
signal clicked //对应的信号处理器为:onClicked
signal hovered() //没有参数,括号是可选的 对应的信号处理器为:onHovered
signal performAction(string action, variant actionArgument) 对应的信号处理器为:onPerformAction
}
向一个组件中添加一个信号,便会自动添加一个信号处理器,它使用“on<SignalName>”来命名,这里需要将信号的第一个字母大写。
发射信号就是简单的调用它,就像操作函数一样。在下面的代码中,当单击MouseArea时,它会通过调用rect.ButtonClicked()来发射父对象的ButtonClicked信号。这个信号会被application.qml通过onButtonClicked信号处理器获取:
//Button.qml
import QtQuick 2.0
Rectangle {
id: rect
signal buttonClicked
width: 100; height: 100
MouseArea {
anchors.fill: parent
onClicked: rect.buttonClicked()
}
}
调用Button.qml
import QtQuick 2.4
Button {
width: 100; height: 100
onButtonClicked: console.log("Mouse was clicked")
}
参数的运用
//Button.qml
import QtQuick 2.0
Rectangle {
id: rect
signal buttonClicked(int xPos, int yPos)
width: 100; height: 100
MouseArea {
anchors.fill: parent
onClicked: rect.buttonClicked(mouse.x, mouse.y)
}
}
import QtQuick 2.4
Button {
width: 100; height: 100
onButtonClicked: console.log("Mouse clicked at " + xPos + "," + yPos)
}
3. 将信号关联到其他函数和信号上
信号对象有一个connect()函数,可以用来将一个信号关联到一个函数或者其他的信号上。当一个信号关联到一个函数上,这个函数会在信号发射时自动调用。(在Qt术语中,关联到一个信号上的函数被称为槽;在QML中定义的所有函数都被视为Qt槽)这样信号会被这个函数接收而不是被信号处理器来接收。
import QtQuick 2.4
Item {
id: item
width: 200; height: 200
function myMethod() {
console.log("Button was clicked!")
}
Button {
id: button
anchors.fill: parent
Component.onCompleted: buttonClicked.connect(item.myMethod)
}
}
这样无论何时信号被发射,都会调用myMethod函数。大多情况下,使用信号处理器来接收信号就足够了,因为这里的代码使用connect()函数比以前使用onButtonClicked处理器没有任何的优势。如果要动态创建对象或者集成JavaScript代码,就会发现connect()函数很有用。
import QtQuick 2.4
Item {
id: item
width: 200; height: 200
function myMethod() {
console.log("Button was clicked!")
}
Row {id:row}
Component.onCompleted: {
var component = Qt.createComponent("Button.qml")
for(var i = 0; i < 3; i++) {
var button = component.createObject(row)
button.border.width = 1
button.buttonClicked.connect(myMethod)
}
}
}
使用同样的方法可以关联一个信号到一个动态创建的对象的函数上,或者关联一个信号到一个JavaScript函数上。
还有一个相应的disconnect()函数用来移除关联的信号。
import QtQuick 2.4
Item {
...
function removeSignal() {
button.clicked.disconnect(item.myMethod)
}
}
另外,connect()函数也可以关联一个信号到另一个信号上,这样会产生“转发”信号效果;当相关信号被发射后它会自动被发射。
MouseArea{
anchors.fill: parent
Component.onCompleted: clicked.connect(item.buttonClicked)
}
无论何时MouseArea的clicked信号被发射,rect.buttonClicked信号也会自动被发射。