Qt信号与槽

server/2025/3/16 4:33:13/

1.信号与槽概述

        在Qt中,用户和控件的每一次交互过程称为一个事件。比如“用户点击按钮”是一个事件,“用户关闭窗口”也是一个事件。

        每个事件都会发出一个信号。例如用户点击按钮会发出“按钮被点击”的信号,用户关闭窗口会发出“窗口被关闭”的信号

        Qt中所有控件都具备接收信号的能力,一个控件可以接收多个不同的信号。对于接收的每个信号,控件都会做出相应的响应动作。例如,按钮所在的窗口接收到“按钮被点击”的信号后,会做出“关闭自己”的响应动作;再比如输入框自己接收到“输入框被点击”的信号后,会做出显示闪烁的光标,等待用户输入数据的响应动作。在Qt中,对信号做出的相应动作就称为槽

        信号和槽是Qt特有的消息传输机制,它能将相互独立的控件关联起来。比如,“按钮”和“窗口”本身是两个独立的控件,点击“按钮”并不会对“窗口”造成任何影响。通过信号和槽机制,可以将“按钮”和“窗口”关联起来,实现“点击按钮会使窗口关闭”的效果

        信号的本质:信号是由于用户对窗口或控件进行了某些操作,导致窗口或控件产生了某个特定事件,这时Qt对应的窗口类会发出某个信号,以此对用户的操作做出反应。因此,信号的本质就是事件。如按钮单击、双击,窗口刷新,鼠标移动、按下、释放,键盘输入。

        那么在Qt中信号是通过什么形式呈现给使用者呢?

                我们对哪个窗口进行操作,那个窗口就可以捕捉到这些被触发的事件

                对于使用者来说触发一个事件我们就可以得到Qt框架给我们发送的某个特定信号

                信号的呈现形式就是函数,也就是说某个事件产生了,Qt框架就会调用某个对应的信号函数,通知使用者

        在Qt中信号的发出者是某个实例化的对象

        槽的本质:槽就是对信号响应的函数。槽就是一个函数,与一般的C++函数是一样的,可以定义在类的任何位置(private、public或protected),可以具有任何参数,可以被重载,也可以被直接调用(但是不能有默认参数)。槽函数与一般的函数不同的是:槽函数可以与一个信号关联,当信号被发射时,关联的槽函数被自动执行。

        说明:

        (1)信号与槽机制底层是通过函数间的相互调用实现的。每个信号都可以用函数来表示,称为信号函数;每个槽也可以用函数表示,称为槽函数。例如:“按钮被按下”这个型号可以用clicked()函数表示,“窗口关闭”这个槽可以用close()函数表示,假如使用信号和槽机制实现:“点击按钮会关闭窗口”的功能,其实就是clicked()函数调用close()函数的效果。

        (2)信号函数与槽函数通常位于某个类中,和普通的成员函数相比,他们的特别之处在于

                1.信号函数用signals关键字修饰,槽函数用public slots、protected slots或者private slots修饰。signals和slots是Qt在C++的基础上扩展的关键字,专门用来指明信号函数和槽函数;

                2.信号函数只需要声明,不需要定义(实现),而槽函数需要定义(实现)。

2.信号和槽的使用

2.1 连接信号和槽

        在Qt中,QObject类提供了一个静态成员函数connect(),该函数专门用来关联指定的信号函数和槽函数。

connect()函数原型:

connect(const QObject *sender, const char* signal,const QObject * receiver,const char* methed,Qt::ConnectionType type = Qt::AutoConnection)//sender:信号的发送
//signal:发送的信号(信号函数)
//receiver:信号的接收者
//method:接收信号的槽函数
//type:用于指定关联方式,默认的关联方式为Qt::AutoConnection,通常不需要手动设定。

        代码示例:在窗口中设置一个按钮,当点击“按钮”时关闭“窗口”

//widget.cpp#include "widget.h"
#include "ui_widget.h"
#include <QPushButton>Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget)
{ui->setupUi(this);QPushButton *btn = new QPushButton(this);btn->setText("关闭窗口");connect(btn,&QPushButton::clicked,this,&QWidget::close);
}Widget::~Widget()
{delete ui;
}

        点击后这个窗口会关闭

2.2 查看内置信号和槽

        系统自带的信号和槽通常是通过“Qt帮助文档”来查询。

        如上述示例,要查询“按钮”的信号,在帮助文档中输入:QPushButton

                首先可以在“Contents”中寻找关键字signals

                如果没有找到,继续去父类中查找,因此我们去他的父类QAbstractButton中继续查找关键字signal,这里的clicked()就是要找的信号。槽函数的寻找方式和信号一样,只不过他的关键字是slot

2.3 通过Qt Creator生成信号槽代码

        Qt Creator可以快速帮助我们生成信号槽相关的代码

        代码示例:在窗口中设置一个按钮,当点击“按钮”是关闭“窗口”。

        1.新建项目(前文详细讲过这里不赘述)

        2.进入UI设计界面

                3.在UI设计窗口中拖入一个“按钮”,并且修改“按钮”的名称及字体的大小等

        4.可视化生成槽函数先对按钮右键,然后点击“转到槽”之后,出现如下界面;对于按钮来说,当点击是发送的信号是:clicked(),所以此处选择:clicked()

        5.自动生成槽函数原型框架;

        (1)在“widget.h”头文件中自动添加槽函数的声明

        说明:自动生成槽函数的名称有一定的规则。槽函数的命名规则为:on_XXX_SSS,其中;

        1.以“on”开头,中间使用下划线连接起来;

        2.“XXX”表示的是对象名(控件的objectName属性)

        3.“SSS”表示的是对应的信号

        如:“on_pushButton_clicked()”,pushButton代表的是对象名,cliced是对应的信号

        (2)在“widget.cpp”中自动生成槽函数定义

        6.在槽函数函数定义中添加要实现的功能,实现关闭窗口的效果

3.自定义信号与槽

        使用“emit”关键字发送信号。“emit”是一个空的宏。“emit”其实是可选的,没有什么含义,只是为了提醒开发人员

示例1:

        1、在widget.h中声明自定义的信号与槽,如图所示;

        2.在“widget.cpp”中实现槽函数,并且关联信号和槽

        这里可以通过Alt+Enter快捷键为声明的函数添加定义

        还可以通过Shift+F2在函数的声明和定义之间快速切换。

示例2:当老师说“上课了”,学生就“回到座位,开始学习”

1.在源文件中新建两个类,一个是老师类,一个是学生类;首先选中项目名称,鼠标右键------》“add new”

        点击后出现如下界面

选择“choose”出现如下界面

注意:

        在Qt中新建类时,要选择新建类的父类

        显然,当前项⽬中还没啥类适合做新类的⽗类, 同时新的类也不是⼀个 "窗⼝" 或者 "控件". 这种情况⼀般选择 QObject 作为基类.

       这样做的好处是这个新类的对象可以搭配 Qt 的对象树机制. 便于对象的正确释放.

下一步,出现如下界面

        对于学生类,以上述同样的方式进行添加,添加完成后,项目目录新增文件如下:

        在teacher.h中声明信号函数

        在student.h中声明槽函数

        在 widget.h 中实例化 "⽼师类对象" 和 "学⽣类对象";

        在student.cpp中实现槽函数

        在“widget.cpp”中连接自定义信号与槽

案例3:老师点击“按钮”触发学生上课

        运行结果如下


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

相关文章

Android7上移植I2C-tools

一&#xff0c;下载源码 cd hardware/libhardware/tests git clone https://git.kernel.org/pub/scm/utils/i2c-tools/i2c-tools.git 二&#xff0c; 在 i2c-tools 目录添加 Android.mk 编译文件 LOCAL_PATH: $(call my-dir)################### i2c-tools ###############…

HCIA-11.以太网链路聚合与交换机堆叠、集群

链路聚合背景 拓扑组网时为了高可用&#xff0c;需要网络的冗余备份。但增加冗余容易后会出现环路&#xff0c;所以我们部署了STP协议来破除环路。 但是&#xff0c;根据实际业务的需要&#xff0c;为网络不停的增加冗余是现实需要的一部分。 那么&#xff0c;为了让网络冗余…

随笔小记-本人常用桌面应用(流程图-boardmix,截图-snipaste,文件比较-beyond compare,远程控制-向日葵,解压-360压缩)

1.流程图绘画-boardmix 2.快捷截图-snipaste 3.文件与文件夹比较工具&#xff08;比较文件内容差异结构差异&#xff0c;可合并&#xff09;-beyond compare 4.远程控制-向日葵远程控制 5.压缩包的解压缩-360压缩

微信小程序threejs三维开发

微信小程序threejs开发 import * as THREE from three; const { performance, document, window, HTMLCanvasElement, requestAnimationFrame, cancelAnimationFrame, core, Event, Event0 } THREE .DHTML import Stats from three/examples/jsm/libs/stats.module.js; im…

影刀RPA安装32位与64位的差别

1. 影刀RPA概述 1.1 产品简介 影刀RPA是一款由杭州分叉智能科技有限公司研发的RPA自动化软件&#xff0c;致力于为各行业客户提供RPA自动化机器人产品与解决方案&#xff0c;能够实现PC、手机上的任何软件自动化操作。其功能特性丰富&#xff0c;包括桌面软件自动化、网页自动…

第十五届蓝桥杯C/C++ C 组全部题目详细题解

本文为第十五届蓝桥杯C/C C 组全部题目的详细题解&#xff0c;题目均来自于蓝桥杯官网&#xff0c;真题链接&#xff1a; 蓝桥杯真题卷 - 蓝桥云课 觉的有帮助或者写的不错可以点个赞&#xff0c;如果我题解写的有问题也欢迎评论指出&#xff0c;欢迎友好讨论 目录 题一:拼正方…

使用OpenCV和MediaPipe库——抽烟检测(姿态监控)

目录 抽烟检测的运用 1. 安全监控 (1) 公共场所禁烟监管 (2) 工业安全 2. 智能城市与执法 (1) 城市违章吸烟检测 (2) 无人值守管理 3. 健康管理与医疗 (1) 吸烟习惯分析 (2) 远程监护 4. AI 监控与商业分析 (1) 保险行业 (2) 商场营销 5. 技术实现 (1) 计算机视…

Golang倒腾一款简配的具有请求排队功能的并发受限服务器

golang官方指南[1]给了一些代码片段&#xff0c;层层递进演示了信道的能力: 1>. 信号量2>. 限流能力 var sem make(chan int, MaxOutstanding) func Serve(queue chan *Request) {for req : range queue {req: reqsem <- 1 go func() { // 只会开启MaxOutstandin…