【快速上手QT】03-信号与槽connect

这篇具有很好参考价值的文章主要介绍了【快速上手QT】03-信号与槽connect。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

信号与槽

都说信号与槽是QT的精髓(别问谁说的,问就是我说的),那么我们首先先知道什么是信号和槽。

信号就是信号,可以由任何组件去发送,而QT提供的组件可可以发送信号,比如QPushButton(没错,还是以它为例),当我们按下QPushButton的时候,实际上QPushButton会发出信号,那为什么我们看不到任何变化呢,那是因为我们没有给这个信号绑定槽函数。

绑定之后,每当我们绑定的信号发出后,QT会自动执行我们绑定的槽函数。

简单来说就是A给B发个信号,然后B去执行槽函数。

接下来我们直接写一段代码来实验一下,马上就明白是怎么回事了。

初体验

【快速上手QT】03-信号与槽connect,快速上手QT,qt,开发语言

如上图,我给一个QPushButton绑定了一个来自于主界面的槽函数,一旦点击之后便会打印调试信息“button1 click”。

下面是主界面的头文件以及cpp文件

#pragma once

#include <QtWidgets/QMainWindow>
#include "ui_Zhetu.h"

class Zhetu : public QMainWindow
{
    Q_OBJECT

public:
    Zhetu(QWidget *parent = nullptr);
    ~Zhetu();

public slots:
    void ButtonClick(void);

private:
    Ui::ZhetuClass ui;
};

上面是头文件,我们只需要注意一点,那就是public slots:

我们一个组件类的公共槽函数就写在这里面,和public:以及private:没有什么不一样的。 

#include "Zhetu.h"

#include <QPushButton> 
#include <qdebug.h>

void Zhetu::ButtonClick(void) {
	qDebug() << "button1 click";
}

Zhetu::Zhetu(QWidget *parent): QMainWindow(parent){
	this->setFixedSize(500, 500);

	QPushButton* button1 = new QPushButton("button1", this);

	connect(button1, &QPushButton::clicked, this, &Zhetu::ButtonClick);
}

Zhetu::~Zhetu()
{}

上面是cpp文件,我在主界面的构造函数里创建了一个QPushButton,并且通过connect函数给这个按钮绑定了一个信号槽。

上面代码的意思就是绑定了button1的点击(clicked),只要button1被点击了,那么就会发出一个信号,信号谁会去接收呢,就是connect的第三个参数去接收,this也就是我们的主界面,主界面接收到来自button1的点击信号之后会去调用主界面下的槽函数ButtonClick。

在ButtonClick函数中我们只有一句代码,也就是打印调试信息(不知道这个写法没关系,记住就好了,QT中我们很少打印的)。

connect

经过上面的例子,相信小伙伴们应该对信号槽有了一些了解了。接下来我们就介绍一下connect的几种用法(因为它有好多重载版本)。

第一种

第一种用法就是我上面演示的例子

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

第一个参数填入信号的发送者,比如说我们的按钮,那就直接把按钮的这个对象传进去。

第二个参数的发送者发送的信号,这个信号我们可以通过QT助手去查找。我们的QPushButton里没有信号,那么我们就去它的父类里寻找,也就是QAbstractButton。

【快速上手QT】03-信号与槽connect,快速上手QT,qt,开发语言

可以看出一共有四种信号,相信大家通过英文名字都可以知道这些信号是什么意思,就比如说我们刚刚例子里用的clicked,那就是点击按钮的时候发送的信号。

第三个参数传入接收者,我在例子中写的是this,也就是说我Zhetu类来接收。

第四个参数传入槽函数的地址,我们自己定义的类的自定义槽函数的声明我们写在头文件的publish slots:中,可以参考上面的代码例子。

这样我们就算完成了信号与槽的绑定,只要信号发送了,那么我们的接收者就会调用绑定好的槽函数。

如果像我上面那样绑定槽函数,在槽函数里只是打印一句话,那么是不是没有接收者的事,不管谁是接收者,我都可以打印一句话。所以实际上我们在第四个参数的位置可以随便传入一个参数,不一定非要是接收者的槽函数。

【快速上手QT】03-信号与槽connect,快速上手QT,qt,开发语言

那么既然都跟接收者没有关系了,我是不是连接收者都可以省略。

第二种

【快速上手QT】03-信号与槽connect,快速上手QT,qt,开发语言

这就是第二种用法,如果我的槽函数是随便一个函数(不是其他类的槽函数),那么connect只需要三个参数。

connect(发送者,信号,执行函数)

前两个参数与上面一致,第三个参数传入执行函数的地址。

但是要注意的是,如果执行函数是其他类的槽函数,那么就不能用这第二种用法,必须要指定接收者。

也就是说,要么就不用其他类的槽函数,一旦用了,那么接受者就要写上这个类的对象。

第三种

上面的用法是QT5之后的,QT4的话,connect有别的用法。

【快速上手QT】03-信号与槽connect,快速上手QT,qt,开发语言

connect(button1, SIGNAL(clicked(bool)), this, SLOT(ButtonClick(void)));

简单来说就是信号和槽函数分别需要用不同的宏给包裹起来,分别是SOGNAL以及SLOT

还有一点要注意的就是写上信号函数与槽函数的时候需要加上参数类型,参考一下上面的例子。

所以说QT4的写法还是比较麻烦的,不过这是向下兼容的,QT5可以用QT5和QT4的写法,而QT4只能用QT4的写法。不过话又说回来了,现在QT都出到6了,QT4除了老项目以外应该也用的比较少了,所以这第三种用法(QT4)大家了解一下就行。

槽函数的参数

上面QT4的写法中我们知道写信号函数以及槽函数的时候需要写上参数类型,那么就引申出新的问题了,槽函数还可以有参数?该怎么给槽函数传参数呢?

这个就得看我们的信号了,实际上信号也是函数,信号也有参数,当然我们使用QT人家组件的信号的时候我们是无法决定给信号的参数是什么的,这个在后面将自定义信号的时候会说。

总之就是信号函数的参数就是传给槽函数的参数。

【快速上手QT】03-信号与槽connect,快速上手QT,qt,开发语言

还是以我们QPushButton的clicked这个信号为例,它有一个参数,是布尔类型的,所以实际上我们给这个信号绑定的槽函数是可以有一个可读取到的bool的参数的。

但是我们之前的例子很明显,绑定的槽函数都是没有任何参数的,所以信号传递的参数我们没有接收,接下来我们再写一段代码去验证一下能不能接收到来自信号的参数。

#include <qdebug.h>

void hello(bool a) {
	qDebug() << a;
}

Zhetu::Zhetu(QWidget *parent): QMainWindow(parent){
	this->setFixedSize(500, 500);

	QPushButton* button1 = new QPushButton("button1", this);

	connect(button1, &QPushButton::clicked, &hello);
}

【快速上手QT】03-信号与槽connect,快速上手QT,qt,开发语言

我们是可以接受到来自信号的数据的,但是我们发现传递的这个永远是false。

此时这个参数实际上是不生效的,也就是一直都是传给我们默认值也就是false。我们加一行代码让这个参数生效即可。

button1->setCheckable(true);

【快速上手QT】03-信号与槽connect,快速上手QT,qt,开发语言

当这个参数生效之后我们可以发现,接受的数据是true和false交替着来的,也就是说我们可以通过修改槽函数的形参列表来获取信号发送来的数据。

我们槽函数的形参数量可以比信号的形参数量少,但是不能比信号的形参多,否则会出现错误。

自定义信号与槽

我们知道了信号和槽都是函数,那么既然是函数,能不能重载呢?

答案是可以的。

但是我目前没看到有QT自带的组件的信号有重载的,那么相应的,信号的参数都是只有一种,没有重载,那么接收信号的数据的槽函数自然也是没有重载的了。

因此要实现重载功能,我们就需要自己去自定义信号和槽,没错,信号也是我们可以自己创建的。

自定义信号

自定义信号实际上就是我们去声明一个函数,这个函数要求是无返回值的。

我们写在头文件中的signals:里,可以参考下面的代码。

【快速上手QT】03-信号与槽connect,快速上手QT,qt,开发语言

这样就算是完成了自定义的信号了,没错,信号只需要声明而不需要实现,可以有参数可以重载。

现在的问题就在于我们自定义的信号什么情况下会发送,人家QT自带的组件的信号都是我们有所操作的时候会自动发送,而我们自己定义的信号呢?那就只能是手动发送信号了。

使用emit就可以发送我们的自定义信号了,甚至还可以直接把参数写上。

emit this->MySignal();

重载之后就会有一个问题,我们使用connect的时候传入信号与槽的时候都是直接写函数名的,那人家咋知道你这个信号到底是你重载的哪个版本的信号,槽函数又是重载的哪个版本的槽函数呢? 

答案就是函数指针,我们在connect绑定之前先创建好重载函数的函数指针,在创建函数指针的时候我们就把参数类型指定好,这样就不会有因为重载而出现歧义的情况出现了。

问题都解决之后我们就可以写代码来实验一下了。

#include "Zhetu.h"

#include <QPushButton> 
#include <qdebug.h>

void Zhetu::MySlot(void) {
	qDebug() << "button1 void";
}

void Zhetu::MySlot(int) {
	qDebug() << "button1 int";
}

void Zhetu::test(void) {
	emit this->MySignal();
	emit this->MySignal(1);
}


Zhetu::Zhetu(QWidget *parent): QMainWindow(parent){
	this->setFixedSize(500, 500);

	QPushButton* button1 = new QPushButton("button1", this);

	connect(button1, &QPushButton::clicked, this, &Zhetu::test);

	void (Zhetu:: * fun1)(void) = &Zhetu::MySlot;
	void (Zhetu:: * sig1)(void) = &Zhetu::MySignal;
	connect(this, sig1, this, fun1);

	void (Zhetu:: * fun2)(int) = &Zhetu::MySlot;
	void (Zhetu:: * sig2)(int) = &Zhetu::MySignal;
	connect(this, sig2, this, fun2);

}

【快速上手QT】03-信号与槽connect,快速上手QT,qt,开发语言

由于我们无法自动的发出信号,我们只能手动去发送,因此我还是先给按钮绑了一个信号槽,当按钮按下时触发名为test的槽函数。在test里我们手动发送信号,并且我们在发送的时候发送了两条信号,因为一个有参数一个没有参数,因此在发送的时候我们不需要考虑重载的问题。

在绑定重载信号和重载槽函数的时候,我们就需要在调用connect之前就把对应的函数指针创建好,并且指定好参数,这样重载的问题就解决了。

在上图我们也可以看出,我们是可以正常地发送重载信号也可以正常地使用重载槽函数去接收信号了。文章来源地址https://www.toymoban.com/news/detail-833910.html

到了这里,关于【快速上手QT】03-信号与槽connect的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • QT 信号与槽

     .h文件 .cpp文件 现象

    2024年02月02日
    浏览(42)
  • qt中的信号与槽

    connect有好几种形式 连接方式有 连接类型 说明 Qt::AutoConnection 如果发送者和接收者在同一线程,使用Qt::DirectConnection,否则使用Qt::QueuedConnection Qt::DirectConnection 信号被发射时立即执行,信号和槽函数在同一线程 Qt::QueuedConnection 在事件循环回到接收者线程后执行槽函数,信号和槽

    2024年02月07日
    浏览(41)
  • QT基础【5-信号与槽】

    🌈个人主页:godspeed_lucip 🔥 系列专栏:QT从基础到进阶 推荐使用这种写法,信号名字、槽函数名字写错了,编译器会直接报错 参数解释: 第一个参数:信号的发出者 第二个参数:发出的信号 第三个参数:信号的接受者 第四个参数:处理的槽函数 效果: 信号槽机制不只在

    2024年02月21日
    浏览(43)
  • QT的核心——信号与槽

    目录 回顾C 语言信号 1、信号与槽 2、关联信号与槽 2.1自动关联信号与槽 2.2手动关联信号与槽 2.3断开信号与槽 3、自定义信号 3.1自定义信号使用条件 3.2自定义槽函数使用条件 4、信号与槽参数传递 4.1自定义一个带参的信号 4.2关联带参的信号与槽 4.3发送一个带参的信号 5、信

    2024年02月12日
    浏览(50)
  • 2、QT的信号与槽

    connect(信号的发送者,SIGNAL(信号名称),信号的接收者,SLOT(槽函数)); QT 4 的写法 QT 5的写法 控件生成信号定义: ①、在需要接收信号的类中 声明槽函数 ②、在xxx.cpp 中实现槽函数 ③、进行信号与槽的关联 用户自定义信号: ①、在信号的发送者类中声明信号 ②、关联信号与槽

    2024年02月10日
    浏览(44)
  • Qt——Qt工作原理:事件驱动、信号与槽机制

    Qt作为一个现代的GUI(图形用户界面)框架,采用了事件驱动的编程范式,并引入了信号与槽机制,以实现高度交互和松耦合的程序设计。下面详细解释了相关概念,以及如何在Qt中使用它们。 事件是在GUI应用程序中的控件上产生的各种动作、操作或状态变化,例如鼠标移动

    2024年02月10日
    浏览(43)
  • Qt 之 QPushButton,信号与槽机制

    当我们开发基于Qt框架的图形用户界面(GUI)应用程序时,经常需要在界面上添加按钮来实现用户交互。Qt提供了一个名为 QPushButton 的类作为按钮控件的实现。QPushButton是Qt中的标准按钮类,旨在简化按钮的创建和使用。 头文件 :#include QPushButton QPushButton 用于 接受用户点击事

    2024年02月12日
    浏览(49)
  • QT中信号与槽机制的介绍,以及信号与槽连接的几种方式

    功能:实现多个组件之间的相互通信,是QT引以为傲的核心机制 信号:就是信号函数,定义在类体的signals权限下,是一个不完整的函数,只有声明没有定义; 槽:就是槽函数,定义在类体的slots权限下,是一个完整的函数,既有声明也有定义,也可以当做普通函数被使用 无

    2024年02月10日
    浏览(48)
  • QT信号与槽的第五个参数

    1、Qt::AutoConnection: 默认值,使用这个值则连接类型会在信号发送时决定。如果接收者和发送者在同一个线程,则自动使用Qt::DirectConnection类型。如果接收者和发送者不在一个线程,则自动使用Qt::QueuedConnection类型。 2、Qt::DirectConnection:槽函数会在信号发送的时候直接被调用,

    2024年02月13日
    浏览(51)
  • Qt (ui界面)信号与槽函数 组件连接

    重点:信号与槽连接机制。 难点:信号与槽函数的 参数使用。 头函数: 原函数: 测试函数: 测试结果:

    2024年02月14日
    浏览(45)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包