学过QT的都知道,信号与槽是QT非常重要的一大特性之一;
在QT中使用connect函数去绑定信号和槽函数,那么在QML中如何绑定呢?
一般都是使用Connections组件就行信号与槽的连接,也推荐使用此种方式链接。
1 定义信号
格式:
signal 信号名(参数1, ...)
例如:
定义信号名为testSig,有两个参数,第一个参数是字符串类型,第二个参数是int类型;
signal testSig(string name, int value)
发射信号:
直接像函数那样调用即可!
testSig("小明", 20)
2 绑定槽函数
2.1 方式一
直接在信号名前面加上on,然后信号名首字母改为大写即可;
// 信号与槽会自动绑定
onTestSig: {
console.log("name = ", name, " value = ", value)
}
2.2 方式二
使用Connections组件,内部可以使用target属性指定需要绑定发射信号的对象,然后再使用方式一中的方法进行信号与槽的绑定;
// 定义槽函数绑定信号
Connections {
target: root // 信号发送者
onTestSig: {
console.log(name + " " + value)
}
}
2.3 方式三(推荐)
使用Connections组件,内部可以使用target属性指定需要绑定发射信号的对象,然后再使用function关键字去定义槽函数,槽函数的命名需要与方式一一致,但是这里需要指定参数,与信号一致;
// 定义槽函数绑定信号
Connections {
target: root // 信号发送者
// 推荐使用此种方式
function onTestSig(iName, iValue) {
console.log(iName + " " + iValue)
}
}
这样就可以知道有什么样的参数可以使用了。
2.4 代码测试案例
// 定义信号
signal testSig(string name, int value)
Button {
id: btn
width: 100; height: 50
onClicked: {
// 发射信号
testSig("小明", 20)
}
}
// 默认会与信号绑定
onTestSig: {
console.log("name = ", name, " value = ", value)
}
// 定义槽函数绑定信号
Connections {
target: root // 信号发送者
// 推荐使用此种方式
function onTestSig(iName, iValue) {
console.log(iName + " " + iValue)
}
// 其次是这种方式
// onTestSig: {
// console.log(name + " " + value)
// }
}
点击按钮后就可以发射信号出去;
这里打印了两次,因为代码中信号与槽绑定了两个函数;
3 跨文件的信号与槽绑定
如果信号定义在一个qml文件中,槽函数在另一个qml文件中,这时候如果需要绑定,那么就得将相应的id传给参函数所在的qml文件中了;
第一个qml(信号所在)
Button {
id: btn111
y: 400
width: 100
height: 50
background: Rectangle {
anchors.fill: parent
border.color: "red"
}
signal btnSig2(string value) // 定义信号
onClicked: {
btnSig2("777")
}
}
Component {
id: com
Button {
signal btnSig(string value) // 定义信号
onClicked: {
btnSig("666")
}
}
}
// 将id转过去
MyComponent {
com1: com
com2: com
btn: btn111
}
第二个MyComponent.qml(槽函数所在)
Rectangle {
width: 400
height: 300
// 定义变量存储id值
property Component com1
property Component com2
property Button btn
border.color: "black"
Loader {
id: loader1
sourceComponent: com1 // 加载组件对象,而不是从文件加载。这个属性允许开发者直接指定一个QML组件作为加载目标
anchors.bottom: parent.bottom
anchors.bottomMargin: 20
anchors.right: parent.right
anchors.rightMargin: 20
Connections {
target: loader1.item // 这里不能直接使用 com1 ,因为com1是被Loader动态加载的,所以需要使用loader1.item拿到的值才可以
ignoreUnknownSignals: true // 忽略没有连接上信号所发出的错误
function onBtnSig(value) {
console.log("right ", value);
}
}
}
Loader {
id: loader2
sourceComponent: com2
anchors.bottom: parent.bottom
anchors.bottomMargin: 20
anchors.right: parent.right
anchors.rightMargin: 150
Connections {
target: loader2.item // 不能直接使用 com2
ignoreUnknownSignals: true // 忽略没有连接上信号所发出的错误
function onBtnSig(value) {
console.log("left ", value)
}
}
}
Connections {
target: btn // 可以直接使用 btn ,因为btn是在另外一个qml文件中加载了的,所以可以直接使用传过来的id
function onBtnSig2(value) {
console.log("lalalalala", value)
}
}
}
得到信号发送方的id后,剩下的就是信号与槽的绑定了;重点是如何将id传过去;
另外可以定义一个qml文件用于另外两个qml信号与槽的绑定。
ignoreUnknownSignals: true // 忽略没有连接上信号所发出的错误
即如果信号丢失,或者说信号被注释了被删除了,如果没有设置这个属性为true,程序运行时就会报错!
例如将btnSig2信号给注释掉后,就会报错;因为在绑定槽函数的地方没有设置ignoreUnknownSignals: true;
好了,初步学习qml信号与槽的绑定,内容差不多就是这些;我也是刚开始接触的小白,后续深入学习后,或者在项目中遇到更好的方式后再来补充吧!