QML 具有信号和处理程序机制。当发出信号时,会调用相应的信号处理程序。
QML 信号和处理程序事件系统是 QML 中非常重要的概念。信号是一种用于通知其他对象发生了某些事件的机制,而处理程序则是接收并处理这些事件的函数或方法。
(相关资料图)
在 QML 中,每个对象都可以定义自己的信号和处理程序。当对象发生特定事件时,它会向其注册的所有处理程序发送相应的信号。其他对象可以监听这些信号,并执行相应的操作来响应该事件。
一、使用信号处理程序接收信号
要在为特定对象发出特定信号时接收通知,对象定义应声明一个名为 on
例如,来自 Qt Quick Controls 模块的 Button 类型有一个 clicked 信号,只要单击按钮就会发出该信号。在这种情况下,用于接收此信号的信号处理程序应为 onClicked:
import QtQuickimport QtQuick.ControlsRectangle{id: rectwidth: 250; height: 250Button{anchors.bottom: parent.bottomanchors.horizontalCenter: parent.horizontalCentertext: \"Change color!\"onClicked:{rect.color = Qt.rgba(Math.random(), Math.random(), Math.random(), 1);}}}
1.1、属性更改信号处理程序
当 QML 属性的值发生变化时,会自动发出信号。 这种类型的信号是属性更改信号,这些信号的信号处理程序以 on
【领 QT开发教程 学习资料, 点击下方链接莬费领取↓↓ ,先码住不迷路~】
点击这里:
例如,TapHandler 类型的 pressed 属性:
import QtQuickRectangle{id: rectwidth: 100; height: 100TapHandler{onPressedChanged: console.log(\"taphandler pressed?\", pressed)}}
1.2、信号参数
信号可能有参数。要访问这些,应该为处理程序分配一个函数。可以使用箭头函数和匿名函数。
示例:
// Status.qmlimport QtQuickItem{id: myitemsignal errorOccurred(message: string, line: int, column: int)}Status{onErrorOccurred: (mgs, line, col) =>console.log(`${line}:${col}: ${msg}`)}
注意:函数中形式参数的名称不必与信号中的名称匹配。
如果不需要处理所有参数,则可以省略尾随参数:
Status{onErrorOccurred: function (message) { console.log(message) }}
不能遗漏前导参数,但是可以使用一些占位符名称来向读者表明它们并不重要:
Status{onErrorOccurred: (_, _, col) =>console.log(`Error happened at column ${col}`)}
可以使用纯代码块代替函数,但不鼓励使用。在这种情况下,所有信号参数都被注入到块的作用域中。但是,这会使代码难以阅读,因为不清楚参数的来源,并导致 QML 引擎中的查找速度变慢。 不推荐以这种方式注入参数,如果实际使用该参数会导致运行时警告。
1.3、使用连接类型
在某些情况下,可能需要访问发出它的对象之外的信号。为了这些目的,QtQuick 模块提供了 Connections 类型来连接到任意对象的信号。Connections 对象可以接收来自其指定目标的任何信号。
示例:
import QtQuickimport QtQuick.ControlsRectangle{id: rectwidth: 250; height: 250Button{id: buttonanchors.bottom: parent.bottomanchors.horizontalCenter: parent.horizontalCentertext: \"Change color!\"}Connections{target: buttonfunction onClicked(){rect.color = Qt.rgba(Math.random(), Math.random(), Math.random(), 1);}}}
1.4、附加的信号处理程序
附加信号处理程序从附加类型而不是在其中声明处理程序的对象接收信号。
例如,Component.onCompleted 是一个附加的信号处理程序。它通常用于在其创建过程完成时执行一些 JavaScript 代码。下面是一个例子:
import QtQuickRectangle{width: 200; height: 200color: Qt.rgba(Qt.random(), Qt.random(), Qt.random(), 1)Component.onCompleted:{console.log(\"The rectangle"s color is\", color)}}
QML 引擎自动将具有完成信号的 Component 附加类型的对象附加到 Rectangle 对象。创建 Rectangle 对象时,引擎会发出此信号,从而触发 Component.onCompleted 信号处理程序。
二、向自定义 QML 类型添加信号
可以通过 signal 关键字将信号添加到自定义 QML 类型。
定义新信号的语法是:
signal [([[, ...]])]
2.1、通过将信号作为方法调用来发出信号。
示例:
// SquareButton.qmlimport QtQuickRectangle{id: rootsignal activated(real xPosition, real yPosition) //定义信号property point mouseXYproperty int side: 100width: side; height: sideTapHandler{id: handleronTapped: root.activated(root.mouseXY.x, root.mouseXY.y) //发出信号onPressedChanged: root.mouseXY = handler.point.position}}现在 SquareButton 的任何对象都可以使用 onActivated 信号处理程序连接到激活的信号:// myapplication.qmlSquareButton{onActivated: (xPosition, yPosition)=>console.log(\"Activated at \" + xPosition + \",\" + yPosition)}
信号对象有一个 connect() 方法来将信号连接到一个方法或另一个信号。当信号连接到方法时,只要发出信号,就会自动调用该方法。 这种机制使信号能够由方法而不是信号处理程序接收。
下面,使用 connect() 方法将 messageReceived 信号连接到三个方法:
import QtQuickRectangle{id: relaysignal 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)}}
使用 connect() 允许多个方法接收信号。此外,connect() 在将信号连接到动态创建的对象时很有用。
有一个对应的 disconnect() 方法用于移除连接的信号:
Rectangle{id: relay//...function removeTelegraphSignal(){relay.messageReceived.disconnect(sendToTelegraph)}}
3.1、信号到信号连接
通过将信号连接到其他信号,connect() 方法可以形成不同的信号链。
import QtQuickRectangle{id: forwarderwidth: 100; height: 100signal send()onSend: console.log(\"Send clicked\")TapHandler{id: mouseareaanchors.fill: parentonTapped: console.log(\"Mouse clicked\")}Component.onCompleted:{mousearea.tapped.connect(send) // 信号连接到信号}}
每当 TapHandler 的 tapped 信号发出时,send() 信号也将自动发出。输出:
MouseArea clicked
Send clicked
【领 QT开发教程 学习资料, 点击下方链接莬费领取↓↓ ,先码住不迷路~】
点击这里:
Copyright © 2015-2022 华南经贸网版权所有 备案号:粤ICP备18025786号-52 联系邮箱: 954 29 18 82 @qq.com