【QT】信号与槽

QT 元对象系统

概念

Qt 元对象系统(Meta-Object System, MOS) 是 Qt 框架中的一个 核心机制,用于 支持信号与槽、运行时类型信息(RTTI)、动态属性 等功能。

在 C++ 语言本身中,没有原生的反射(Reflection)机制,无法在运行时获取类的元信息(如类名、方法、属性等)。Qt 通过元对象系统 解决了这个问题,使得 Qt 的 信号槽、对象属性系统、事件处理等功能成为可能

在 Qt 所有能使用信号与槽的类,必须依赖 QObject 元对象类! 信号与槽的功能是在QObject类中的实现!

QT 继承关系图 只要继承了 QObject 都是元对象

元对象与对象直接是有依赖关系的,一个子对象的产生,一般要依赖一个父对象!

信号与槽函数

信号与槽函数机制是QT编程的基础,也是QT的一大创新,是通过QT的元对象系统实现。信号(Signal)就是在特定条件下被发射的事件。比如QPushButton 最常见的信号就是鼠标单击时发射clicked()信号。当信号被发射出去之后,很多时候我们需要对这个信号进行响应处理,对信号进行响应的函数称之为 槽函数,槽函数跟一般的函数用法一样,只不过槽函数可以跟信号进行关联。当信号被发射时,槽函数将会自动执行。

信号与槽函数关联

自动关联

注意:自动关联仅适用于 UI 设计文件里面,看的到的才能自动关联。

手动关联

语法

//QT4:关联语法  👉不检测信号与槽的参数是否匹配

connect(信号发送者地址,SIGNAL(信号名称),信号的接收者地址,SLOT(槽函数名称));
例子:connect(this,SIGNAL(mysig()),this,SLOT(myslot()));

//QT5:关联语法  👉自动检测信号与槽的参数是否匹配

connect(信号发送者地址,&发送者类名::信号名称,信号的接收者地址,&接收者类名::槽函数名称);
例子:connect(this,&MainWindow::mysig,this,&MainWindow::myslot);

实现过程

技巧

  • 声明完槽函数后右键槽函数可选择重构即可自动帮你生成函数定义

自定义信号

QT允许用户在一个类中自定义信号

1️⃣ 类内声明,即头文件声明

2️⃣ 类外实现,在.cpp 文件实现关联信号 connect和发送信号emit的函数

这里仅做测试所以在构造函数触发,后面实际触发自定义信号可以在其他函数里面触发。

信号与槽的参数传递

1️⃣ 自定义一个带参的信号

2️⃣ 自定义一个带参数的槽

3️⃣ 关联带参的信号与槽

4️⃣ 发送与接收参数

注意事项

信号带参数,槽函数可以带参数,也可以不带参数

区别:

  • 槽函数带参数,参数类型必须跟信号保持一致,表示槽函数接收信号传递过来的参数
  • 信号参数的个数必须 大于或等于 槽函数参数个数
  • 槽函数不带参数,表示我不想接收信号传递过来的参数
  • 如果信号没有任何参数,此时槽函数也不可以有任何参数
    • 信号带了参数,connect写的时候不要写参数的名字,只需要写参数的类型
    • 槽函数带了参数,connect写的时候不要写参数的名字,只需要写参数的类型

信号与槽的一对多相互关联

先说结论

1️⃣ 同一个槽函数,可以被不同对象的信号关联

2️⃣ 同一个信号,可以关联不同的槽函数

  • 槽函数的调用顺序跟你关联的先后顺序一致,先关联的先调用

接下来看代码实现

情况一:同一个槽函数,可以被不同对象的信号关联


情况二: 同一个信号,可以关联不同的槽函数


获取信号的发送者及按钮的值

作用:当多个组件对象共用一个槽函数的时候,程序员需要知道是哪个组件对象触发的信号,此时就要获取信号的发送者

QObject *sender() const
//返回值:返回一个指针,该指针指向信号的发送者

获取按钮上的值

上面获取到按钮的发送着之后返回的指针是父类的指针,这个指针 p 没有 text 方法,所以我们需要将父类指针转化成子类才能使用 text 方法,转换使用 qobject_cast<QPushButton*>(p)

//要求你点击某个按钮的时候,获取这个按钮的字面值(按钮上的文字,QPushButton里面有个text方法返回字面值)
//编译报错:p的类型是QObject类,这个类里面没有text方法
//QString str=p->text();

//把QObject类型(父类)转换成QPushButton(子类)
 QPushButton *mybt=qobject_cast<QPushButton *>(p);
QString str=mybt->text();
qDebug()<<"你点击的按钮字面值是: "<<str;

信号取消关联

//QT4:取消关联语法 
 
disconnect(信号发送者地址,SIGNAL(信号名称),信号的接收者地址,SLOT(槽函数名称));
//例子:disconnect(this,SIGNAL(mysig()),this,SLOT(myslot()));
 
//QT5:取消关联语法
 
disconnect(信号发送者地址,&发送者类名::信号名称,信号的接收者地址,&接收者类名::槽函数名称);
//例子:disconnect(this,&MainWindow::mysig,this,&MainWindow::myslot);
 
//注意:关联的时候采用的语法版本需要与取消关联的语法版本匹配!QT4 -> QT4 系统默认的关联QT4 
                                                      //QT5 -> QT5

信号槽与lambda表达式

如果在设计信号与槽的关联时,槽函数使用的功能比较简单,就可以直接使用 lambda来代替!

优点:节省槽函数的代码量!

lambda 表达式语法: 
[捕捉列表](参数列表)->返回值类型 
{
     //函数主体
}
常见的捕捉方式有:
    按值捕捉 [=]:捕捉外部变量的副本(即按值传递)。
    按引用捕捉 [&]:捕捉外部变量的引用(即按引用传递)。
    捕捉特定变量 [x]:只捕捉指定变量。
    混合捕捉 [=, &x]:按值捕捉外部所有变量,但按引用捕捉 x
-----------------------------------------------------------------------------------
//手动关联并用lambda 实现槽函数  👉[&] 全部捕捉 
connect(ui->pushButton, &QPushButton::clicked,this,[&]()   
{ 
    qDebug() << "按钮被点击" << endl; 
    //i++ 是对一个外部变量 i 的引用操作。
    //在 Lambda 表达式内部,可以修改 i 的值,而这种修改会影响到外部的 i
    ui->label->setNum(i++); 
});

书接上回,继续第一章的学习管理系统继续完善。可以看下我上一章的示例内容
QT新手基础入门(超详细)

要求:

  实现点击登陆按钮自动判断账号密码是否正确,然后输出对应信息。输错会清空账号密码框。

  连续输错三次账号密码,自动锁定账号密码和登陆按钮,无法继续点击。

  密码框旁边利用按钮做一个 显示/隐藏 的图标,点击后可 显示/隐藏 密码。

Qtproject.zip

信号与槽的总结

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值