QT学习笔记-信号与槽(干货)

发布时间 2023-12-05 15:45:50作者: Jev_0987

一、什么是信号和槽(Signal and Slot)

可以和进程间通信的信号机制联系。

signal(信号,信号处理函数) // 进程间的通信方式

其中,该函数的作用就是接收到【信号】后应该做什么样的处理【信号处理函数】。

对应到QT中,信号就还是信号,槽函数就对应了信号处理函数。

举个例子:

窗口主体有个关闭按钮,点击这个按钮窗口就会关闭,那么关闭按钮是发送信号的对象,它发送的信号是点击,接受信号的对象是窗口,响应信号的槽是关闭窗口。

image

二、信号和槽点代码实例

(1)Qt4使用宏

Qt4版本中,主要是用connect + 宏的方式进行通信连接。

connect(发送对象,信号,接受对象,槽函数)

其中发送信号和槽函数需要使用SIGNAL()和SLOT()来进行声明。

例如 ,关闭窗口的例子,可以这样写:

connect(ui->pushButton, SIGNAL(clicked()), this, SLOT(close()));

自定义槽函数:需要先将槽函数的声明添加到类的slots中。比如我们对一个QlineEdit控件添加一个接受textEdited信号的槽函数onTextEdited

#ifndef HOME_H
#define HOME_H

#include <QWidget>
#include <QDebug>
#include <QString>

QT_BEGIN_NAMESPACE
namespace Ui { class Home; }
QT_END_NAMESPACE

class Home : public QWidget
{
    Q_OBJECT

public:
    Home(QWidget *parent = nullptr);
    ~Home();
    
private slots:
    void func(QString);
private:
    Ui::Home *ui;
};
#endif // HOME_H

实现函数,使用connect与信号连接

#include "home.h"
#include "ui_home.h"

Home::Home(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Home)
{
    ui->setupUi(this);
    connect(ui->lineEdit, SIGNAL(textEdited(QString)), this, SLOT(func(QString)));
}

void Home::func(QString s)
{
    qDebug()<<s;
}

Home::~Home()
{
    delete ui;
}

image

这样写的好处是信号和槽函数直观,缺点是因为使用宏,编译时不做类型检查,如果有问题的时候只能运行的时候才能发现。

(2)Qt5新的connect函数

Qt5推出了新的connect函数,不需要使用SIGNAL()和SLOT()宏,可以在编译时做类型检查。

#ifndef HOME_H
#define HOME_H

#include <QWidget>
#include <QDebug>
#include <QString>

QT_BEGIN_NAMESPACE
namespace Ui { class Home; }
QT_END_NAMESPACE

class Home : public QWidget
{
    Q_OBJECT

public:
    Home(QWidget *parent = nullptr);
    ~Home();
    void func(QString);
private:
    Ui::Home *ui;
};
#endif // HOME_H
#include "home.h"
#include "ui_home.h"

Home::Home(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Home)
{
    ui->setupUi(this);
//    connect(ui->lineEdit, SIGNAL(textEdited(QString)), this, SLOT(func(QString)));
    connect(ui->lineEdit, &QLineEdit::textEdited, this, &Home::func);

}

void Home::func(QString s)
{
    qDebug()<<s;
}

Home::~Home()
{
    delete ui;
}

Qt5的connect函数中,信号和槽函数的参数都是函数指针,当信号或槽函数有重载时,使用函数指针可以明确告诉编译器使用哪个重载函数,避免歧义。

(3)使用QT creator 洁面添加信号的槽函数(右键-转到槽)

直接通过 Qt Creator界面来完成发送信号和槽函数的连接,右键-转到槽

image

选择信号

image

实现槽函数

#include "home.h"
#include "ui_home.h"

Home::Home(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Home)
{
    ui->setupUi(this);
//    connect(ui->lineEdit, SIGNAL(textEdited(QString)), this, SLOT(func(QString)));
    connect(ui->lineEdit, &QLineEdit::textEdited, this, &Home::func);

}

void Home::func(QString s)
{
    qDebug()<<s;
}

Home::~Home()
{
    delete ui;
}

void Home::on_pushButton_clicked()
{
    qDebug()<<"自动生成的槽函数";
}

image