QT学习笔记—信号和槽

连接信号和槽的函数

connect(信号的发送者, 发送的信号, 信号的接收者, 信号的处理(槽));
  • 信号和槽都可以理解是函数。

  • 信号可以连接信号

  • 一个信号可以连接多个槽

  • 多个信号也连一个槽

  • 信号和槽的参数必须一一对应

  • 信号的参数个数可以多于槽函数的参数个数

信号槽优点:

松散耦合,信号发送和接收端没有关联
需要关联的时候就使用connect()
#include "mywidget.h"
#include 

myWidget::myWidget(QWidget *parent)
    : QWidget(parent)
{
    setWindowTitle("widget窗口");   //设置窗口标题

    this->setFixedSize(600, 400);  //设置窗口固定大小

    QPushButton *btn = new QPushButton;  //创建一个button
    btn->move(100, 200);
    btn->setText(tr("第一个按钮"));
    btn->setParent(this);    //设置button的父类
    btn->show();           //将button显示出来
    //     发送者  发送的信号             信号接受者 信号的处理
    connect(btn, &QPushButton::clicked, this, &myWidget::close);
    //设置信号和槽,点按钮关闭窗口
}

myWidget::~myWidget()
{

}

通过Qt助手可以查看QPushButton支持的信号:

QT学习笔记—信号和槽_第1张图片

QPushButto一些信号:
QT学习笔记—信号和槽_第2张图片

自定义信号和槽

自定义信号(函数):

返回值:void
只需要声明不需要实现
可以有参数,可以重载

自定义槽(函数):

返回值:void
需要声明需要实现
可以有参数,可以重载

示例

jack类:

#ifndef JACK_H
#define JACK_H

#include 

class Jack : public QObject
{
    Q_OBJECT
public:
    explicit Jack(QObject *parent = nullptr);
    void say();

signals:
    void loveYou();    //信号  只需要声明
public slots:

};

#endif // JACK_H
#include "jack.h"

Jack::Jack(QObject *parent) : QObject(parent)
{

}

void Jack::say()
{
    emit this->loveYou(); //emit发送信号
}

Rose类:

#ifndef ROSE_H
#define ROSE_H

#include 

class Rose : public QObject
{
    Q_OBJECT
public:
    explicit Rose(QObject *parent = nullptr);

signals:  //信号函数写在这

public slots:  
     void responseForJack();   //槽  无返回值,无参数,也可以有参数(可以重载)
};

#endif // ROSE_H
#include "rose.h"
#include 

Rose::Rose(QObject *parent) : QObject(parent)
{

}
//槽函数
void Rose::responseForJack()
{
    qDebug() << "I don't love you";
}

mywidget类;

#ifndef MYWIDGET_H
#define MYWIDGET_H

#include 
#include "jack.h"
#include "rose.h"

class myWidget : public QWidget
{
    Q_OBJECT         //有这个东西才能使用信号和槽的机制

public:
    myWidget(QWidget *parent = 0);
    ~myWidget();

    Jack *jack;
    Rose *rose;
};

#endif // MYWIDGET_H
#include "mywidget.h"
#include 

myWidget::myWidget(QWidget *parent)
    : QWidget(parent)
{
    setWindowTitle("widget窗口");   //设置窗口标题

    this->setFixedSize(600, 400);  //设置窗口固定大小

    QPushButton *btn = new QPushButton;  //创建一个button
    btn->move(100, 200);
    btn->setText(tr("第一个按钮"));
    btn->setParent(this);    //设置button的父类
    btn->show();           //将button显示出来
  //设置信号和槽,点按钮关闭窗口
    connect(btn, &QPushButton::clicked, this, &myWidget::close);  

    rose = new Rose;  //实例化对象
    jack = new Jack;

    connect(jack, &Jack::loveYou, rose, &Rose::responseForJack); //设置信号和槽
      
    jack->say();   //发送信号
}

myWidget::~myWidget()
{

}

信号和槽重载的解决

class Jack : public QObject
{
    Q_OBJECT
public:
    explicit Jack(QObject *parent = nullptr);
    void say();
    void say(QString str);

signals:
    void loveYou();    //信号  只需要声明
    void loveYou(QString str);  //重载,带参的信号
public slots:

};

void Jack::say()
{
    emit this->loveYou();
}

void Jack::say(QString str)
{
    emit this->loveYou(str);
}


class Rose : public QObject
{
    Q_OBJECT
public:
    explicit Rose(QObject *parent = nullptr);

signals:

public slots:
     void responseForJack();   //槽  无返回值,无参数,也可以有参数(可以重载)
     void responseForJack(QString str); // 重载槽
};

void Rose::responseForJack()
{
    qDebug() << "I don't love you";
}

void Rose::responseForJack(QString str)
{
    qDebug() << str;
    qDebug() << "I don't love you";
}

连接有参数的信号和槽:

//用函数指针指定重载的信号和槽
void (Jack:: *jackSignal)(QString) =  &Jack::loveYou;  
void (Rose:: *roseSlot)(QString) =  &Rose::responseForJack;
connect(jack, jackSignal, rose, roseSlot); 

jack->say("Rose I love u");

连接无参数的信号和槽:

 //用函数指针指定重载后的信号和槽
void (Jack:: *jackSignal1)(void) =  &Jack::loveYou; 
void (Rose:: *roseSlot1)(void) =  &Rose::responseForJack;
connect(jack, jackSignal1, rose, roseSlot1);

信号连接信号:

void (Jack:: *jackSlot)(void) = &Jack::loveYou;
connect(btn, &QPushButton::clicked, jack, jackSlot); //通过点击按钮发送信号

myWidget构造函数:

#include "mywidget.h"
#include 

myWidget::myWidget(QWidget *parent)
    : QWidget(parent)
{
    setWindowTitle("widget窗口");   //设置窗口标题
    this->setFixedSize(600, 400);  //设置窗口固定大小

    rose = new Rose(this);
    jack = new Jack(this);

//    connect(jack, &Jack::loveYou, rose, &Rose::responseForJack); //设置信号和槽
   //重载后用函数指针指定重载后的函数
    void (Jack:: *jackSignal)(QString) =  &Jack::loveYou; 
    void (Rose:: *roseSlot)(QString) =  &Rose::responseForJack;
    connect(jack, jackSignal, rose, roseSlot);
  //重载后用函数指针指定重载后的函数
    void (Jack:: *jackSignal1)(void) =  &Jack::loveYou;  
    void (Rose:: *roseSlot1)(void) =  &Rose::responseForJack;
    connect(jack, jackSignal1, rose, roseSlot1);

    jack->say("Rose I love u");

    QPushButton *btn = new QPushButton;  //创建一个button
    btn->move(100, 200);
    btn->setText(tr("say"));
    btn->setParent(this);    //设置button的父类
    btn->show();           //将button显示出来

    void (Jack:: *jackSlot)(void) = &Jack::loveYou;
    connect(btn, &QPushButton::clicked, jack, jackSlot);
}

QT4版本信号和槽的连接

connect(jack, SIGNAL(loveYou()), rose, SLOT(responseForJack()));
connect(jack, SIGNAL(loveYou(QString)), rose, SLOT(responseForJack(QString)));

优点:

可以很方便选择有参数的信号连接和无参数信号连接,参数直观

缺点:

不做类型检查,
这样connect(jack, SIGNAL(loveYou()),rose,SLOT(responseForJack(QString))); 
也是编译通过的,但是达不到目的

你可能感兴趣的:(QT学习)