原理:与C++语法一致,信号、槽函数都可以发生重载,使其在名称不变的情况下,传递过程可以携带参数。
示例说明:我们从一个最普通的信号槽工程中,来修改,对信号、槽进行重载,使信号、槽携带参数。
1. 普通信号 - 工程源码
widget.h
#ifndef WIDGET_H
#define WIDGET_H
#include <QWidget>
#include <QPushButton>
class Widget : public QWidget
{
Q_OBJECT
public:
Widget(QWidget *parent = nullptr);
~Widget();
void sendSignalSlot();
void dealSignalSlot();
signals:
/*
* 信号必须有signals关键字来声明
* 信号没有返回值,但可以有参数
* 信号就是函数的声明,只需声明,无需定义
* 使用:emit mySignal();
* 信号可以重载
*/
void mySignal();
private:
QPushButton btn1;
};
#endif // WIDGET_H
widget.cpp
#include "widget.h"
Widget::Widget(QWidget *parent)
: QWidget(parent)
{
btn1.setParent(this);
btn1.setText("sendText");
btn1.resize(80,25);
btn1.move(100,100);
resize(320, 240);
setWindowTitle("Hello!");
connect(&btn1, &QPushButton::clicked, this, &Widget::sendSignalSlot);
connect(this, &Widget::mySignal, this, &Widget::dealSignalSlot);
}
void Widget::sendSignalSlot()
{
emit mySignal();
}
void Widget::dealSignalSlot()
{
btn1.setText("Done!");
}
Widget::~Widget()
{
}
现象:
- 点击 "sendText" 按钮,按钮文字变为 "Done!"。
![](https://img-blog.csdnimg.cn/2020092209305810.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L01hcmtfbWQ=,size_16,color_FFFFFF,t_70)
2. 带参数的信号、信号重载 - 工程源码
- 信号函数可以发生重载。
- 信号携带参数时,接受的槽函数也必须带参。
- connect使用带参信号时,需要使用函数指针。
- 打印调试信息,需要包含头文件:#include <QDebug>
- 输出字符串需要使用 .toUtf8().data(); 进行转换。
widget.h
#ifndef WIDGET_H
#define WIDGET_H
#include <QWidget>
#include <QPushButton>
#include <QDebug>
class Widget : public QWidget
{
Q_OBJECT
public:
Widget(QWidget *parent = nullptr);
~Widget();
void sendSignalSlot();
void dealSignalSlot();
// 信号带参数,槽函数也要带参
void dealSignalSlotPara(int, QString);
signals:
/*
* 信号必须有signals关键字来声明
* 信号没有返回值,但可以有参数
* 信号就是函数的声明,只需声明,无需定义
* 使用:emit mySignal();
* 信号可以重载
*/
void mySignal();
void mySignal(int, QString);
private:
QPushButton btn1;
};
#endif // WIDGET_H
widget.cpp
#include "widget.h"
Widget::Widget(QWidget *parent)
: QWidget(parent)
{
btn1.setParent(this);
btn1.setText("sendText");
btn1.resize(80,25);
btn1.move(100,100);
resize(320, 240);
setWindowTitle("Hello!");
connect(&btn1, &QPushButton::clicked, this, &Widget::sendSignalSlot);
// 普通信号
void (Widget::*funSingle)() = &Widget::mySignal;
connect(this, funSingle, this, &Widget::dealSignalSlot);
// 带参数信号
void (Widget::*funSinglePara)(int, QString) = &Widget::mySignal;
connect(this, funSinglePara, this, &Widget::dealSignalSlotPara);
}
void Widget::sendSignalSlot()
{
emit mySignal();
emit mySignal(100, "发送信号");
}
void Widget::dealSignalSlot()
{
btn1.setText("Done!");
}
void Widget::dealSignalSlotPara(int a, QString str)
{
qDebug() << a << "\t"<< str;// 我的系统环境中,不用转换也可以输出,不过会将""也一并输出
qDebug() << a << "\t"<< str.toUtf8().data();// 需要加转换,才是正常显示
}
Widget::~Widget()
{
}
现象:
- 窗口现象与原工程一致,点击 "sendText" 按钮,按钮文字变为 "Done!"。
- 并且会在应用程序输出窗口,打印传递的参数。
![](https://img-blog.csdnimg.cn/20200922113455728.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L01hcmtfbWQ=,size_16,color_FFFFFF,t_70)
3. 带参数的槽函数、槽函数重载 - 工程源码
信号可以重载,同理,槽函数也同样可以重载:
widget.h
#ifndef WIDGET_H
#define WIDGET_H
#include <QWidget>
#include <QPushButton>
#include <QDebug>
class Widget : public QWidget
{
Q_OBJECT
public:
Widget(QWidget *parent = nullptr);
~Widget();
void sendSignalSlot();
void dealSignalSlot();
// 槽函数也可以重载。信号带参数,槽函数也要带参。
void dealSignalSlot(int, QString);
signals:
/*
* 信号必须有signals关键字来声明
* 信号没有返回值,但可以有参数
* 信号就是函数的声明,只需声明,无需定义
* 使用:emit mySignal();
* 信号可以重载
*/
void mySignal();
void mySignal(int, QString);
private:
QPushButton btn1;
};
#endif // WIDGET_H
widget.cpp
#include "widget.h"
Widget::Widget(QWidget *parent)
: QWidget(parent)
{
btn1.setParent(this);
btn1.setText("sendText");
btn1.resize(80,25);
btn1.move(100,100);
resize(320, 240);
setWindowTitle("Hello!");
connect(&btn1, &QPushButton::clicked, this, &Widget::sendSignalSlot);
// 普通信号 槽函数也可以重载
void (Widget::*funSingle)() = &Widget::mySignal;
void (Widget::*funDealSignalSlot)() = &Widget::dealSignalSlot;
connect(this, funSingle, this, funDealSignalSlot);
// 带参数信号 槽函数也可以重载
void (Widget::*funSinglePara)(int, QString) = &Widget::mySignal;
void (Widget::*funDealSignalSlotPara)(int, QString) = &Widget::dealSignalSlot;
connect(this, funSinglePara, this, funDealSignalSlotPara);
}
void Widget::sendSignalSlot()
{
emit mySignal();
emit mySignal(100, "发送信号");
}
void Widget::dealSignalSlot()
{
btn1.setText("Done!");
}
void Widget::dealSignalSlot(int a, QString str)
{
qDebug() << a << "\t"<< str;// 我的系统环境中,不用转换也可以输出,不过会将""也一并输出
qDebug() << a << "\t"<< str.toUtf8().data();// 需要加转换,才是正常显示
}
Widget::~Widget()
{
}
现象:
4. Qt4的connect简单写法
用Qt4的写法来写connect信号连接:
(!!!不建议使用,看似写法简单,出了问题很麻烦。因为SIGNAL、SLOT是将函数名称,转换为字符串格式,并且不进行错误检查。一旦写错在编译阶段无任何报错,运行到故障点时才报错,不容易找到错误位置。而且必须用 public slots关键字修饰槽函数。此方法仅做了解,不推荐使用!!!)
widget.h
#ifndef WIDGET_H
#define WIDGET_H
#include <QWidget>
#include <QPushButton>
#include <QDebug>
class Widget : public QWidget
{
Q_OBJECT
public:
Widget(QWidget *parent = nullptr);
~Widget();
public slots:
void sendSignalSlot();
void dealSignalSlot();
// 信号带参数,槽函数也要带参
void dealSignalSlotPara(int, QString);
signals:
/*
* 信号必须有signals关键字来声明
* 信号没有返回值,但可以有参数
* 信号就是函数的声明,只需声明,无需定义
* 使用:emit mySignal();
* 信号可以重载
*/
void mySignal();
void mySignal(int, QString);
private:
QPushButton btn1;
};
#endif // WIDGET_H
widget.cpp
#include "widget.h"
Widget::Widget(QWidget *parent)
: QWidget(parent)
{
btn1.setParent(this);
btn1.setText("sendText");
btn1.resize(80,25);
btn1.move(100,100);
resize(320, 240);
setWindowTitle("Hello!");
connect(&btn1, &QPushButton::clicked, this, &Widget::sendSignalSlot);
// // 普通信号
// void (Widget::*funSingle)() = &Widget::mySignal;
// connect(this, funSingle, this, &Widget::dealSignalSlot);
// // 带参数信号
// void (Widget::*funSinglePara)(int, QString) = &Widget::mySignal;
// connect(this, funSinglePara, this, &Widget::dealSignalSlotPara);
// Qt4信号连接(不建议用,出了错麻烦,而且必须用 public slots关键字修饰槽函数)
// Qt4槽函数必须有public slots关键字来修饰
// 功能等同于上面的用法,不过写错没有错误提示,只有运行时才有调试输出
connect(this, SIGNAL(mySignal()), this, SLOT(dealSignalSlot()));
connect(this, SIGNAL(mySignal(int,QString)),
this, SLOT(dealSignalSlotPara(int,QString)));
}
void Widget::sendSignalSlot()
{
emit mySignal();
emit mySignal(100, "发送信号");
}
void Widget::dealSignalSlot()
{
btn1.setText("Done!");
}
void Widget::dealSignalSlotPara(int a, QString str)
{
qDebug() << a << "\t"<< str;// 我的系统环境中,不用转换也可以输出,不过会将""也一并输出
qDebug() << a << "\t"<< str.toUtf8().data();// 需要加转换,才是正常显示
}
Widget::~Widget()
{
}
现象: