重载的信号槽
函数指针:
int fun(int a,long b)
int (*funp)(int, long) = fun;
实现回调函数就需要函数指针
信号重载
派生类槽函数发送两个信号
派生类给父类发两个信号
void (SubWidget::*mysigsub)() = &SubWidget::sigSub;
connect(&subw,mysigsub,this,&MainWidget::slotShowMe);
void (SubWidget::*mysigsub1)(int,QString) = &SubWidget::sigSub;
connect(&subw,mysigsub1,this,&MainWidget::slotSubMsg);
void MainWidget::slotSubMsg(int number, QString str)
{
qDebug()<<number<<str;
}
既然QT4在函数重载这么好用,为什么不用?
自定义信号槽必须声明
拓展:
一个信号可以和多个槽相连
如果是这种情况,这些槽会一个接一个的被调用,但是槽函数调用顺序是不确定的。像上面的例子,可以将一个按钮点击信号连接到关闭窗口的槽函数,同时也连接到学生请吃饭的槽函数,点击按钮的时候可以看到关闭窗口的同时也学生请吃饭的log也打印出来。
多个信号可以连接到一个槽
只要任意一个信号发出,这个槽就会被调用。如:一个窗口多个按钮都可以关闭这个窗口。
一个信号可以连接到另外的一个信号
当第一个信号发出时,第二个信号被发出。除此之外,这种信号-信号的形式和信号-槽的形式没有什么区别。注意这里还是使用connect函数,只是信号的接收者和槽函数换成另一个信号的发送者和信号函数。
//必须使用函数指针解决重载问题
void (SubWidget::*mysigsub)() = &SubWidget::sigSub;
connect(bt2,&QPushButton::pressed,this,mysigsub);
通过上面的函数,也实现了最终结果
也就是第一个信号发出时,第二个信号也被发出。
槽函数可以使用lambda表达式
完整代码
mainwidget.cpp
#include "mainwidget.h"
#include <QDebug>
MainWidget::MainWidget(QWidget *parent)
: QWidget(parent)
{
this->setFixedSize(400,400);
this->setWindowTitle("QQ登陆");
this->setWindowIcon(QIcon("/home/yangyu/DailyFILE/picture/52.jpg"));
b3 = new QPushButton("登陆",this);
b3->resize(80,40);
b3->move(300,350);
connect(b3,&QPushButton::clicked,this,&MainWidget::slotHideMe);
void (SubWidget::*mysigsub)() = &SubWidget::sigSub;
connect(&subw,mysigsub,this,&MainWidget::slotShowMe);
void (SubWidget::*mysigsub1)(int,QString) = &SubWidget::sigSub;
connect(&subw,mysigsub1,this,&MainWidget::slotSubMsg);
b4 = new QPushButton("注册",this);
b4->resize(80,40);
b4->move(20,350);
connect(b4,&QPushButton::clicked,this,&MainWidget::slotHideMe_login);
connect(&logw,&loginwidget::loginsignal,this,&MainWidget::slotShowMe_login);
}
MainWidget::~MainWidget()
{
}
void MainWidget::slotForMainWidget()
{
b2->setText("注销");
}
void MainWidget::slotHideMe()
{
//隐藏自己,显示QQ邮箱
this->hide();
subw.show();
}
void MainWidget::slotShowMe()
{
show();
subw.hide();
}
void MainWidget::slotHideMe_login()
{
//隐藏自己,显示QQ邮箱
this->hide();
logw.show();
}
void MainWidget::slotShowMe_login()
{
show();
logw.hide();
}
void MainWidget::slotSubMsg(int number, QString str)
{
qDebug()<<number<<str;
}
subwidget.cpp
#include "subwidget.h"
SubWidget::SubWidget(QWidget *parent) : QWidget(parent)
{ //相当于主窗口的一个子窗口
bt1 = new QPushButton(this);
bt1->setText("确认");
bt1->resize(0,350);
bt2 = new QPushButton(this);
bt2->setText("退出");
bt2->resize(80,40);
bt2->move(300,350);
this->setWindowTitle("QQ邮箱");
this->setFixedSize(400,400);
this->setWindowIcon(QIcon("/home/yangyu/DailyFILE/picture/58.jpg"));
connect(bt2,&QPushButton::pressed,this,&SubWidget::MySlot);
}
SubWidget::~SubWidget()
{
}
void SubWidget::MySlot()
{
//隐藏自己,显示QQ邮箱
emit sigSub();//发送信号
emit sigSub(520,"666");//发送信号
}
subwidget.h
#ifndef SUBWIDGET_H
#define SUBWIDGET_H
#include <QWidget>
#include <QPushButton>
class SubWidget : public QWidget
{
Q_OBJECT
public:
explicit SubWidget(QWidget *parent = nullptr);
~SubWidget();
signals:
void sigSub();
void sigSub(int num,QString str);
public slots:
//自定义槽函数
void MySlot();
//void MySlot1();
private:
QPushButton *bt1;//(确认)
QPushButton *bt2;//(退出)隐藏自己,显示QQ登陆
};
#endif // SUBWIDGET_H
mainwidget.cpp
#ifndef MAINWIDGET_H
#define MAINWIDGET_H
#include <QWidget>
#include <QPushButton>
#include "subwidget.h"
#include "loginwidget.h"
class MainWidget : public QWidget
{
Q_OBJECT
public:
MainWidget(QWidget *parent = 0);
~MainWidget();
//自定义槽函数
void slotForMainWidget();
void slotHideMe();
void slotShowMe();
void slotHideMe_login();
void slotShowMe_login();
void slotSubMsg(int number,QString str);
private:
QPushButton* b1;
QPushButton* b2;
QPushButton* b3;//(登陆)隐藏自己显示QQ邮箱
QPushButton* b4;//(注册)隐藏自己显示QQ注册
SubWidget subw;
loginwidget logw;
};
#endif // MAINWIDGET_H
loginwidget.cpp
#include "loginwidget.h"
loginwidget::loginwidget(QWidget *parent) : QWidget(parent)
{
bt1 = new QPushButton(this);
bt1->resize(80,40);
bt1->setText("返回");
bt1->move(300,350);
this->setWindowTitle("QQ注册");
this->setFixedSize(400,400);
connect(bt1,&QPushButton::pressed,this,&loginwidget::loginslots);
this->setWindowIcon(QIcon("/home/yangyu/DailyFILE/picture/50.jpg"));
}
void loginwidget::loginslots()
{
emit loginsignal();//发送自定义信号
}
loginwidget.h
#ifndef LOGINWIDGET_H
#define LOGINWIDGET_H
#include <QWidget>
#include <QPushButton>
class loginwidget : public QWidget
{
Q_OBJECT
public:
explicit loginwidget(QWidget *parent = nullptr);
signals://自定义信号
void loginsignal();
public slots://自定义槽函数
void loginslots();
private:
QPushButton *bt1;//上一页
};
#endif // LOGINWIDGET_H
最终效果
槽函数做lambda表达式
不需要考虑太多,按照下面写
connect(b3,&QPushButton::clicked,this,[=]()
{
b4->setText("lambda");
});
如果槽函数很复杂,那就建议使用槽函数。
如果比较简单,可以使用lambda表达式