【Qt教程】1.7 - Qt5带参数的信号、信号重载、带参数的槽函数、槽函数重载

原理:与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!"。

    

 

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!"。
  • 并且会在应用程序输出窗口,打印传递的参数。

 

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()
{
}

现象

  • 与上面信号重载的现象一致。
©️2020 CSDN 皮肤主题: 黑客帝国 设计师:上身试试 返回首页