qml 信号和处理程序事件系统(Signal and Handler Event System)
时间:2023-06-04 08:37:00
目录标题
- 概述
- 信号处理程序
- 属性变更信号处理程序的属性
- 信号参数
- 关联信号(Connections)
- 附加信号处理
- 添加自定义类型的信号
- 信号连接方法/信号
-
- 使用disconnect()断开信号
- 信号关联信号
概述
QML 具有信号和处理程序机制,其中信号是事件,信号通过信号处理程序响应。
发出信号时,将调用相应的信号处理程序。将脚本或其他操作等逻辑允许组件响应事件放置在处理程序中。
<AttachingType>.on<Signal> //是信号的名称,首字母必须大写 ///我们在处理程序中编写我们想要实现的效果 on<Property>Changed ////属性改变信号处理程序的用法 //是属性的名称,首字母大写 ///都放在当前元素的内部
信号处理程序
在为特定对象发出特定信号时,应接收通知。对象的定义应声明一个名称
on
信号处理程序,包括是信号的名称,首字母大写。信号处理程序应包括调用信号处理程序时要执行的信号处理程序 JavaScript 代码。。
例如,Qt Quick Controls 模块中的 Button 类型有一个 clicked 每次单击按钮,信号都会发出。 在这种情况下,接收该信号的信号处理程序应该是 onClicked。
在下面的示例中,单击按钮时会调用 onClicked 处理程序将随机颜色应用于父亲 Rectangle:
import QtQuick import QtQuick.Controls Rectangle { id: rect width: 250; height: 250 Button { anchors.bottom: parent.bottom anchors.horizontalCenter: parent.horizontalCenter text: "Change color!" onClicked: { rect.color = Qt.rgba(Math.random(), Math.random(), Math.random(), 1); } } }
属性更改信号处理程序
当 QML 属性的值发生变化时,会自动发出信号。 这种类型的信号是属性更改信号,这些信号的信号处理程序以 onChanged 的形式编写,其中 是属性的名称,第一个字母大写。
例如,MouseArea 类型有一个pressed 属性。 要在此属性更改时接收通知,下例为一个名为 onPressedChanged 的信号处理程序:import QtQuick Rectangle { id: rect width: 100; height: 100 TapHandler { //点击屏幕时,修改了pressed属性,触发onPressedChanged onPressedChanged: console.log("taphandler pressed?", pressed) } }
信号参数
信号可能有参数。 要访问这些,您应该为处理程序分配一个函数。 箭头函数和匿名函数都可以工作。
示例// Status.qml import QtQuick //注意:函数中形式参数的名称不必与信号中的名称相匹配。 Item { id: myitem signal errorOccurred(message: string, line: int, column: int) }
Status { onErrorOccurred: (mgs, line, col) => console.log(`${ line}:${ col}: ${ msg}`) //不需要参数时 onErrorOccurred: function (message) { console.log(message) } }
关联信号(Connections)
在某些情况下,可能希望访问发出该信号的对象之外的信号。为此,该QtQuick模块提供用于连接任意对象信号的Connections类型。可以接收来自它的指定的任何信号的目标。
使用场景:
- 将多个对象链接到同一个信号上
- 在发出信号的作用域之外来建立连接
- 发射信号的对象没有在QML中定义
例如,前面示例中的 onClicked 处理程序可能已被根 Rectangle 接收,方法是将 onClicked 处理程序放置在其目标设置为按钮的 Connections 对象中:
import QtQuick import QtQuick.Controls Rectangle { id: rect width: 250; height: 250 Button { id: button anchors.bottom: parent.bottom anchors.horizontalCenter: parent.horizontalCenter text: "Change color!" } Connections { //关联button的clicked信号 target: button function onClicked() { rect.color = Qt.rgba(Math.random(), Math.random(), Math.random(), 1); } } }
附加信号处理
对象本身或者其基类没有的属性和信号,需要通过外部(附加类型)提供,从附加类型接收一个信号并进行处理
import QtQuick 2.14 Rectangle { width: 200; height: 200 color: Qt.rgba(Qt.random(), Qt.random(), Qt.random(), 1) Component.onCompleted: { //Component 附加类型 console.log("The rectangle's color is", color) } }
自定义类型添加信号
可以通过signal关键字将信号添加到自定义QML类型。定义新信号的语法为:
signal <name>[([<type> <parameter name>[, ...]])]
// SquareButton.qml import QtQuick 2.14 Rectangle { id: root signal activated(real xPosition, real yPosition) //定义一个信号 property point mouseXY property int side: 100 width: side; height: side TapHandler { id: handler onTapped: root.activated(mouseXY.x, mouseXY.y) //发送信号 onPressedChanged: mouseXY = handler.point.position } } // myapplication.qml SquareButton { //处理activated信号 onActivated: console.log("Activated at " + xPosition + "," + yPosition) }
信号连接方法/信号
信号对象使用connect()连接方法或另一个信号。当信号连接到方法时,只要发出信号,该方法就会自动调用。这种机制使信号可以通过方法而不是信号处理程序来接收,也可以通过disconnect()来取消连接.
import QtQuick 2.14 Rectangle { id: relay signal messageReceived(string person, string notice) //定义信号 Component.onCompleted: { relay.messageReceived.connect(sendToPost) //关联信号 relay.messageReceived.connect(sendToTelegraph) relay.messageReceived.connect(sendToEmail) relay.messageReceived("Tom", "Happy Birthday") } function sendToPost(person, notice) { console.log("Sending to post: " + person + ", " + notice) } function sendToTelegraph(person, notice) { console.log("Sending to telegraph: " + person + ", " + notice) } function sendToEmail(person, notice) { console.log("Sending to email: " + person + ", " + notice) } }
使用disconnect()断开信号
Rectangle { id: relay //... function removeTelegraphSignal() { relay.messageReceived.disconnect(sendToTelegraph) } }
信号关联信号
import QtQuick 2.14 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) //关联信号 }