【Qt】自定义信号和槽函数

server/2025/3/17 8:07:09/

🏠个人主页:Yui_
🍑操作环境:Qt Creator
🚀所属专栏:Qt

在这里插入图片描述

文章目录

  • 1. 自定义槽函数
    • 1.1 基础语法
    • 1.2 使用`connect`连接信号
    • 1.3 使用函数名字的方式来自动连接
  • 2.自定义信号函数
  • 3.知识补充
    • 3.1 signals和slots
    • 3.2 emit
  • 4. 总结

在Qt中,允许自定义信号和槽函数。
其中自定义槽函数是非常频繁的,但是自定义信号函数频率较低,这是由于Qt中内置的信号几乎可以覆盖到用户的操作,简单来说就是用户的操作是可以穷举的。尽管如此,学习自定义的信号函数也是有必要的。
在下面的文章,我们会先讲解更重要的自定义槽函数再去讲解自定义信号。

1. 自定义槽函数

1.1 基础语法

  • 在早期的Qt版本要求槽函数必须写到public solts下,但是在现在的高版本的Qt(Qt5及以上)允许写到类public作用域或者全局下。
  • 返回值为void,需要声明,也需要实现。
  • 可以到参数,可以重载。
    绑定自定义的槽函数有两种方法:
  1. 通过connect函数连接信号。
  2. 通过函数名字的方式来自动连接。
    下面会详细的演示这两种方法。

1.2 使用connect连接信号

这种方式在之前的文章就已经有所涉及了。
关于connect函数的介绍可以看这篇文章【Qt-信号与槽】connect函数的用法-CSDN博客

#include "widget.h"
#include "ui_widget.h"Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget)
{ui->setupUi(this);button = new QPushButton(this);button->setText("我是一个按钮~");button->move(100,100); // 移动位置到(100,100)像素connect(button,&QPushButton::clicked,this,&Widget::handle);
}Widget::~Widget()
{delete ui;
}void Widget::handle()
{button->setText("被点击了~");
}

头文件:

#ifndef WIDGET_H
#define WIDGET_H#include <QWidget>
#include <QPushButton>
QT_BEGIN_NAMESPACE
namespace Ui { class Widget; }
QT_END_NAMESPACEclass Widget : public QWidget
{Q_OBJECTpublic:Widget(QWidget *parent = nullptr);~Widget();
public slots://可以不写void handle();private:Ui::Widget *ui;QPushButton* button;
};
#endif // WIDGET_H

运行效果:

sinal_1.gif

1.3 使用函数名字的方式来自动连接

双击fromfile中的ui文件
image.png
进入图形化构建的界面。
拖动PushButton控件到中间的界面,右键控件点击转到槽。
image.png
然后再点击箭头所☞的内容。
image.png
点吉ok后,回到主界面,可以看到这样的界面
image.png

这个就是系统自动生成的槽函数,有个这个槽函数我们就不要在显示的写connect函数,下面看演示:

#include "widget.h"
#include "ui_widget.h"Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget)
{ui->setupUi(this);
}Widget::~Widget()
{delete ui;
}void Widget::on_pushButton_clicked()
{ui->pushButton->setText("被点击了~");
}
#ifndef WIDGET_H
#define WIDGET_H#include <QWidget>QT_BEGIN_NAMESPACE
namespace Ui { class Widget; }
QT_END_NAMESPACEclass Widget : public QWidget
{Q_OBJECTpublic:Widget(QWidget *parent = nullptr);~Widget();private slots:void on_pushButton_clicked();private:Ui::Widget *ui;
};
#endif // WIDGET_H

signal_2.gif

有人有疑问吗?为什么不用connect就可以关联信号的槽?
其实也不是没有,只是Qt也自动生成了,而且还有格式要求,打开widget.ui文件,
不知道怎么打开的话看这篇文章:【Qt】初始项目代码解释-CSDN博客的目录5
widget.ui:
image.png
在这个自动生成的文件中,可以看到一个类似于connect的函数。Qt在调用自动生成的槽函数时就会调用这个函数。
所有这自动生成的槽函数的名字也是有严格的要求的,一下是要求:
命名规则on_xxx_sss

  1. on开头,中间使用下滑线连接起来。
  2. xxx表示的是对象名,控件的objectName属性。
  3. SSS表示的对应的信号
    注意:
    如果我们通过图形化界面场景控件的话,就推荐这种快速的方式连接函数和槽。
    如果我们是通过代码的方式创建的控件,还是推荐手动的写connect.(你的代码中也没有connectSlotByName

2.自定义信号函数

基础语法

  1. 自定义信号函数必须写到signals下。
  2. 返回值为void,只需要声明,不需要实现。
  3. 可以有参数,也可以发生重载。

自定义信号函数的本质也就是一个特殊函数而已,这是真的,下面我们会开始演示。

#include "widget.h"
#include "ui_widget.h"Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget)
{ui->setupUi(this);connect(this,&Widget::mySignal,this,&Widget::handle);//emit mySignal(); }Widget::~Widget()
{delete ui;
}void Widget::handle()
{this->setWindowTitle("自定义信号喵~");
}
#ifndef WIDGET_H
#define WIDGET_H#include <QWidget>QT_BEGIN_NAMESPACE
namespace Ui { class Widget; }
QT_END_NAMESPACEclass Widget : public QWidget
{Q_OBJECTpublic:Widget(QWidget *parent = nullptr);~Widget();
signals:void mySignal();public slots:void handle();private:Ui::Widget *ui;
};
#endif // WIDGET_H

image.png

运行后发现什么变化都没有呢,这是因为我们没有调用啊。
我们把注释放开

#include "widget.h"
#include "ui_widget.h"Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget)
{ui->setupUi(this);connect(this,&Widget::mySignal,this,&Widget::handle);emit mySignal(); }Widget::~Widget()
{delete ui;
}void Widget::handle()
{this->setWindowTitle("自定义信号喵~");
}

image.png

这样就成功发出信号了,这个信号是不是就相当于函数,调用这个信号就是发出信号。
再修改修改代码

#include "widget.h"
#include "ui_widget.h"Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget)
{ui->setupUi(this);connect(this,&Widget::mySignal,this,&Widget::handle);}Widget::~Widget()
{delete ui;
}void Widget::handle()
{this->setWindowTitle("自定义信号喵~");
}void Widget::on_pushButton_clicked()
{emit mySignal();
}

signal_4.gif

3.知识补充

3.1 signals和slots

无论是signals还是slots都是Qt字节扩展出来的关键字,不是C+标准中的语法。
除此之外Qt里还大量的使用了元编程的技术(根据代码生成代码)
qmake在构建Qt项目的时候,就会调用专门的扫描器,扫描代码中的关键字,基于关键字自动生成一大堆相关的代码。

3.2 emit

emit也就是发射的意思,作用是发出信号,emit是一个空的宏,emit是可选的,不加也不会影响自定义信号函数的发生。
即便如此,在实际的开发中,还是建议大家,把emit加上,这样的话可读性会变高~

4. 总结

在Qt中,允许自定义信号和槽函数。
自定义槽函数在实际的开发中使用是非常频繁的,不可能不学,自定义信号函数尽管在实际的开发中使用不多,但是还是不得不学啊。
希望本文对你理解自定义信号和槽函数有帮助~


往期文章:
【Qt】初始项目代码解释-CSDN博客
【Qt】HelloWorld程序-CSDN博客
【Qt-信号与槽】connect函数的用法-CSDN博客


http://www.ppmy.cn/server/175353.html

相关文章

leetcode 75.颜色分类(荷兰国旗问题)

题目描述 题目分析 本题是经典的「荷兰国旗问题」&#xff0c;由计算机科学家 Edsger W. Dijkstra 首先提出。 要想单独解决这道题本身还是很简单的&#xff0c;统计0、1、2的数量然后按顺序赋值&#xff0c;或者手写一个冒泡排序&#xff0c;whatever。 但是在这一题中我们主…

JavaScript基本知识

文章目录 一、JavaScript基础1.变量&#xff08;重点&#xff09;1-1 定义变量及赋值1-2 变量的命名规则和命名规范判断数据类型&#xff1a; 2.数据类型转换2-1 其他数据类型转成数值2-2 其他数据类型转成字符串2-3 其他数据类型转成布尔 3.函数3-1函数定义阶段3-2函数调用阶段…

软考高级《系统架构设计师》知识点(十三)

系统架构设计 软件架构的概念 一个程序和计算系统软件体系结构是指系统的一个或者多个结构。结构中包括软件的构件&#xff0c;构件的外部可见属性以及它们之间的相互关系。 体系结构并非可运行软件。确切地说&#xff0c;它是一种表达&#xff0c;使软件工程师能够&#xff1a…

unity基础——线段与拖尾

1、LineRenderer&#xff08;线段渲染器&#xff09; 为空物体加上组件添加材质 选择默认线段的材质 Default—Line Color&#xff1a;可以修改颜色Corner Vertices&#xff1a;角顶点 圆滑度 End Cap Vertices&#xff1a;边缘顶点 线段编辑 1、可以移动线段点的位置&#xf…

Linux 系统蓝牙音频服务实现分析

Linux 系统蓝牙音频服务实现分析 蓝牙音频设备连接管理Linux 系统中,蓝牙音频服务实现为系统音频服务 PulseAudio 的可加载模块,它用来以 PulseAudio 标准的方式描述蓝牙音频设备,将其嵌入 PulseAudio 的音频处理流水线,并呈现给用户,支持用户切换音频设备,如蓝牙耳机。 …

DeepSeek-R1大模型微调技术深度解析:架构、方法与应用全解析

1. DeepSeek-R1大模型架构设计与技术特性 1.1 架构设计 DeepSeek-R1作为超大规模语言模型,其核心架构设计包含以下创新: 专家混合架构(MoE) 采用6710亿参数的混合专家架构(MoE),每个推理过程仅激活370亿参数,实现计算效率与资源利用率的突破性提升。 Transformer框架…

(学习总结28)Linux 基本命令3

Linux 基本命令3 工具使用命令使用 vim 编辑器命令 vim使用 nano 文本编辑器命令 nano使用 gcc/g 编译器命令 gcc/g使用 gdb/cgdb 调试器命令 gdb/cgdb使用自动化构建命令 make使用版本控制器命令 git 系统或进程相关命令读取输入并赋值给变量命令 read设置或修改 shell 环境命…