每日一言
生活就像登山,过程虽累,但山顶的风景值得一切辛苦。
信号与槽
上面我们完成了记事本的前端雏形,很好看了,所以我们现在要实现功能了
我们要先学信号与槽,就是什么意思呢,比如我们点击按钮会发送一个信号给指定的对象,槽就是可以指定对象返回功能,就是利用信号与槽的概念我们来实现功能
接下来我来介绍信号与槽的使用方法
我这边定义了6个按钮
首先我们看到下方的+号,这个就是QT编译器自带的添加信号与槽进行联立的方式
我们点击后可以选择发送者和接受者,以及信号与槽,这边我们想要点击按钮实现,关闭窗口的功能,那么信号选择这个clicked(),发送者就是这个按钮的名字,因为我们要让窗口关闭,所以接收者是这个widget,就是这个窗口,然后槽里面就是选择close(),
那么我们运行点击按钮后,现象就是点击后窗口关闭。
这个就是简单的信号与槽的使用方法。。
还有一种用法
就是点击这个
我们点击一个按钮,鼠标进行拖动,那么就会出来一个线,然后放开,放开后进行配置连接,也可以实现,但是和我们之前的用法其实是一样的,因为就是两个操作方式,但是都是一样的。
但是没什么用,因为这个是QT的一些简单的信号与槽的使用。案例太局限了,主要就是给我们看一下信号与槽的概念是什么,这样说是最好的解释了
好了现在介绍4种信号与槽的常用用法
我只想说的是,都硬记,没什么好解释的
QObject 是 Qt 框架的核心基类,所有 Qt 对象都直接或间接继承自它。在 Qt 中,信号与槽机制、对象树管理、事件系统 等核心功能都依赖于 QObject
QObject::connect 是 Qt 中用于 信号与槽(Signal & Slot)机制 的核心函数,这是 Qt 实现对象间通信的关键方式。下面详细解释它的用法、原理和注意事项:
一、基本语法与参数
1. 旧语法(字符串方式)
QObject::connect(
sender, // 发送信号的对象指针
SIGNAL(signal()), // 信号,用 SIGNAL() 宏包裹
receiver, // 接收信号的对象指针
SLOT(slot()) // 槽函数,用 SLOT() 宏包裹);
2. 新语法(函数指针方式,推荐)
QObject::connect(
sender, // 发送信号的对象指针
&SenderClass::signal, // 信号的函数指针
receiver, // 接收信号的对象指针
&ReceiverClass::slot // 槽函数的函数指针);
3. 参数说明
- sender:发出信号的对象,如 QPushButton* button。
- signal:信号的名称,旧语法用 SIGNAL(信号名()),新语法用 &类名::信号名。
- receiver:接收信号的对象,如 this(当前类实例)。
- slot:槽函数的名称,旧语法用 SLOT(槽名()),新语法用 &类名::槽名。
二、新旧语法对比
1. 旧语法(字符串方式)
connect(button, SIGNAL(clicked()), this, SLOT(onButtonClicked()));
- 优点:
- 兼容性好,支持 Qt 4 和 Qt 5。
- 可以连接非 Q_OBJECT 类的信号(需要特殊处理)。
- 缺点:
- 不检查信号和槽的存在性:如果拼写错误,编译时不会报错,运行时才会崩溃。
- 不支持函数重载:如果信号 / 槽有重载版本,无法指定具体使用哪个。
2. 新语法(函数指针方式,推荐)
connect(button,&QPushButton::clicked,this,&MyClass::onButtonClicked;
这个myclass就是自己的所属于的类
- 优点:
- 编译时检查错误:如果信号或槽不存在,编译器会直接报错。
- 支持函数重载:可以通过函数指针明确指定使用哪个重载版本。
- 支持 Lambda 表达式:可以直接用 Lambda 作为槽函数,无需额外定义槽函数。
- 缺点:
- 要求 Qt 5+,不兼容 Qt 4。
- 必须使用完整的函数签名(包括参数类型)。
我们在看细节解释的时候,发现,我们发现我们的代码中没有继承QObject这个类啊,但是怎么可以直接使用QObject呢,因为:
间接继承了,也是可以的
五、总结
- 隐式继承:如果你的类继承自 QWidget、QMainWindow 等,已经间接继承了 QObject。
- 静态函数:QObject::connect 是静态函数,可直接调用。
- 必须添加 Q_OBJECT 宏:否则信号与槽无法工作。