【QT】重载的信号槽/槽函数做lambda表达式

时间:2024-03-08 08:26:26

重载的信号槽

函数指针:

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表达式