往期回顾:
【QT入门】图片查看软件(优化)-CSDN博客
【QT入门】 lambda表达式(函数)详解-CSDN博客
【QT入门】 Qt槽函数五种常用写法介绍-CSDN博客
【QT入门】 Qt实现自定义信号
一、为什么需要自定义信号
比如说现在一个小需求,我们想要实现跨ui通信,通俗来说,就是两个ui界面,点击一个ui界面的按钮,让另一个ui界面数据变化。此时我们就要自定义信号和槽来实现。
二、自定义步骤
1、创建两个ui界面,每个ui界面创建一个按钮,并绑定相应的槽函数
这一步相对来说很简单的,其中注意一个点,我们如何在原本项目基础上再创建一个ui:
右键单击项目,选择Add New->Qt->Qt设计师界面类即可
2.实现原界面按钮,出现另一个ui界面
这一步同样简单,只需要在原界面按钮槽函数里创建另一个ui界面对象即可
void Widget::on_btnOpen_clicked()
{
SetDialog dig;
dig.exec();//事件循环
}
当用户点击btnOpen按钮时,会触发on_btnOpen_clicked()槽函数。在该槽函数中,创建了一个SetDialog对象dig并调用exec()函数来显示对话框。这样做会弹出另一个界面,因为SetDialog类是一个对话框类,通过调用exec()函数来显示对话框界面,从而实现弹出另一个界面的效果。
3.第三步,也是最重要的一步,点击弹出的ui界面按钮,实现原界面数据变化
首先需要在弹出ui界面定义一个信号函数,当点击此界面ui时执行该信号函数,也就是发送信号,
void SetDialog::on_btnAdd_clicked()
{
static int value=100;
emit on_AddOne_clicked(value++);
}
emit是一个关键字,用于发射(emit)信号。
由于信号的接收方为原ui界面,收到信号后显示数据,所以connect的四个参数明确
connect(&dig,&SetDialog::on_AddOne_clicked,[=](int value){
//用QString的number方法把int类型数据转为QString
ui->lineEdit->setText(QString::number(value));
});
这里因为传递的信号有参数,需要把参数带上,虽说lambda表达式的形参数可以小于等于实际参数数,但是我不写报错了,所以建议大家还是写上。
四个参数一一看:分别是
1、信号的发送者:弹出ui界面对象dig |
2、发送的信号:执行数据改变的信号函数 |
3、信号的接收者:原ui界面 |
4、信号的处理:显示数据在lineEdit上 |
大家对信号和槽机制多理解,在Qt框架中,信号和槽机制是一种用于在不同对象之间进行通信的机制。当某个事件发生时,一个对象可以发射一个信号,而其他对象可以连接到这个信号并执行相应的槽函数,就是某个事件发生会发射一个信号,其他对象可以连接到这个信号,一旦捕获到这个信号就执行相应得操作(槽函数),这样使得不同对象之间通信及其方便。
最终的代码:
void Widget::on_btnOpen_clicked()
{
SetDialog dig;
connect(&dig,&SetDialog::on_AddOne_clicked,[=](int value){
ui->lineEdit->setText(QString::number(value));
});
dig.exec();
}
调用exec()函数显示窗口,会导致进入事件循环,会阻塞UI,直到对话框关闭为止。
这意味着程序会等待用户对对话框的操作完成后,才会继续执行后面的代码。所以connect必须放在exec()方法执行前面。
我们这里的信号槽是用lambda表达式写的,想一下,如果不用,又该怎么写:
void Widget::on_btnOpen_clicked()
{
setDialog dig;
connect(&dig,&setDialog::on_AddOne_clicked,this,&Widget::lineAdd);
dig.exec();
}
所以为什么说用lambda表达式在槽函数代码量少得情况下很好,因为避免了再去写槽函数这个环节,我不用lambda表达式,我就要自己再写一个槽函数,把实现代码写槽函数里面。
至此,我们就实现了一个简单的自定义信号。
都看到这里了,点个赞再走呗朋友~
加油吧,预祝大家变得更强!