当前位置:网站首页>Day18Qt信号与槽2021-10-29

Day18Qt信号与槽2021-10-29

2022-06-21 16:58:00 晓晓暮雨潇潇

Qt对象间的通信机制–信号与槽

1.信号与槽概述

信号与槽用于两个对象之间的通信,为了实现对象间的通信,一些工具包中使用了回调机制(CallBack),而Qt使用信号与槽,这是Qt的核心特征,也是Qt不同于其他开发框架的最突出特征。当一个特殊的事情发生时便可以发射一个信号,比如单击按钮就发射clicked()信号;而槽就是一个函数,它在信号发射后被调用来响应这个信号。

2.优点

1.信号与槽机制是Qt的核心特征,也是Qt不同于其他开发框架最突出的特征;
2.信号和槽的机制是类型安全的,相对于回调机制,类型不安全,无法保证回调调用参数正确;
3.松散耦合,信号发送者不知也不需要知道接收者的信息;
4.信号和槽可以使用任意类型任意数量的参数。

3.信号、槽

1.信号只需要声明,无需也不能定义,需要使用emit发射信号;槽既要声明,也要定义。
2.自定义的信号可以发生重载,(可以有参数),在发生重载时,要使用函数指针明确一个函数地址,告知使用哪个重载版本。槽在发生重载时也一样,语法如下:

void (::*指针名)(参数列表) = &::函数名(重载);

3.信号可以连接信号,可以连接多个槽,当信号发生时,执行顺序将与连接顺序一致。
4.多个信号也可以连接同一个槽函数(例如多个按钮都能关闭窗口)
5.信号和槽函数的参数必须一一对应,包括位置、顺序。
6.信号参数的个数可以多于槽函数的个数,多余的参数将被忽略。
7.信号的声明需要**signals:**关键字,槽函数声明可以使用(public、protected、private)+slots,也可以不使用slots关键字。
8.信号必须是void类型,没有返回值。
9.需要继承自QObject或其子类才可以使用信号与槽机制。
10.在类声明的最开始处添加Q_OBJECT宏,这个一般会自动生成。

4.connect函数

函数原型

connect(信号发送者(对象),信号,信号接收者(对象),槽函数,连接机制);
//如:
connect(btn,&QPushButton::clicked,this,&QWidget::close());

参数5(连接机制)的使用说明

常量描述
Qt::AutoConnection自动关联,默认值、如果信号与槽处于同一个线程,那么使用Qt::DirectConnection,否则使用Qt::QueuedConnection
Qt::DirectConnection发射完信号立即调用槽,只有槽执行完成返回后,发射信号处后面的代码才可以执行(二者在同一线程)
Qt::QueuedConnection队列关联,当控制权返回槽所在线程的事件循环后再执行槽,无论槽执行与否,发射信号之后的代码立即执行
Qt::BlockingQueuedConnection信号线程一直阻塞,直到槽返回,适用于二者在不同的线程
Qt::UniquedConnection防止出现重复关联

5.信号槽关联形式

1.使用connect函数,例如

connect(dlg,SIGNAL(dlgReturn(int),this,SLOT(showValue(int)));//这里分别使用SIGNAL和SLOT关键字修饰信号与槽

2.QT5新增的connect重载形式,不需要使用这两个关键字,例如

connect(dlg.&MyDialog::dlgReturn,this,&Widget::showValue);//可以省略this参数

3.使用匿名函数lamada表达式,形如

connect(dlg,&MyDialog::dlgReturn,[=](int value){
    
	ui->label->setText(value);
});

4.使用设计师工具提供的“转到槽”
在这里插入图片描述
将直接生成槽函数,用户只需实现定义即可

void MyDialog::on_selectBtn_clicked()
{
    
    //槽函数定
}

6.场景

需求:创建两个类,分别是“老师”和“学生”,下课之后,老师发送自定义信号,“饿了”,学生响应该信号,并请老师吃饭。
1.创建两个C++类,一个是Teacher,一个是Student。Teacher中,声明信号hungry

signals:
    void hungry();

2.Student中,声明并实现槽函数treat();

public slots:
    void treat();

void Student::treat(){
    

    qDebug()<<"yxx,我想请你吃牛肉泡馍";
}

3.Qt界面师类widget中,关联信号与槽,并拓展使用了lamada表达式关联信号与信号
widget.cpp中代码如下:

Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
{
    
    ui->setupUi(this);

    //为两个对象分配空间
    yxx0803 = new Teacher(this);
    jackchen = new Student(this);
    connect(yxx0803,&Teacher::hungry,jackchen,&Student::treat);
    classIsOver();
    QPushButton *btn = new QPushButton(this);
    btn->setText("下课!");
    btn->move(100,100);
    connect(btn,&QPushButton::clicked,[=](){
    
       yxx0803->hungry();
    });
}

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

void Widget::classIsOver()
{
    
    emit yxx0803->hungry();
}

4.效果,程序运行,由于classIsOver被调用,会打印一次请客,当点击按钮也会打印请客吃饭。
在这里插入图片描述

原网站

版权声明
本文为[晓晓暮雨潇潇]所创,转载请带上原文链接,感谢
https://blog.csdn.net/weixin_40615338/article/details/121035524