Qt基础(1)Qt信号与槽

本文详细介绍了Qt的信号与槽机制,它是Qt的核心特性,提供了一种类型安全、松散耦合的对象间通信方式。信号在特定事件发生时触发,而槽是响应信号的函数。通过`connect`函数可以建立信号和槽的连接,支持多种连接形式,包括使用匿名函数lambda表达式。文中给出了一个教师和学生类的实例,演示了如何使用信号与槽机制来实现对象间的交互。此外,还讨论了`connect`函数的不同连接类型及其作用。
摘要由CSDN通过智能技术生成

在这里插入图片描述

1.信号与槽概述

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

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

2.信号、槽

  • 信号只需要声明,无需也不能定义,需要使用emit发射信号;槽既要声明,也要定义。
  • 自定义的信号可以发生重载,(可以有参数),在发生重载时,要使用函数指针明确一个函数地址,告知使用哪个重载版本。槽在发生重载时也一样,语法如下:
void (::*指针名)(参数列表) = &::函数名(重载);
  • 信号可以连接信号,可以连接多个槽,当信号发生时,执行顺序将与连接顺序一致。
  • 多个信号也可以连接同一个槽函数(例如多个按钮都能关闭窗口)
  • 信号和槽函数的参数必须一一对应,包括位置、顺序。
  • 信号参数的个数可以多于槽函数的个数,多余的参数将被忽略。
  • 信号的声明需要**signals:**关键字,槽函数声明可以使用(public、protected、private)+slots,也可以不使用slots关键字。
  • 信号必须是void类型,没有返回值。
  • 需要继承自QObject或其子类才可以使用信号与槽机制。
  • 在类声明的最开始处添加Q_OBJECT宏,这个一般会自动生成。

3.connect函数

函数原型

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

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

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

4.信号槽关联形式

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()
{
    //槽函数定
}

5.信号与槽实例

创建两个类,分别是“老师”和“学生”,下课之后,老师发送自定义信号,“饿了”,学生响应该信号,并请老师吃饭。
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被调用,会打印一次请客,当点击按钮也会打印请客吃饭。
在这里插入图片描述

6.传送门

END

🎏文章原创,首发于CSDN论坛。
🎏欢迎点赞❤❤收藏⭐⭐打赏💴💴!
🎏欢迎评论区或私信指出错误❌,提出宝贵意见或疑问❓。


评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

FPGArea

原创不易,请多支持

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值