什么是Qt信号槽机制

2023-11-12

1. 信号和槽概述

信号槽是 Qt 框架引以为豪的机制之一。所谓信号槽,实际就是观察者模式(发布-订阅模式)。当某个`事件`发生之后,比如,按钮检测到自己被点击了一下,它就会发出一个信号(signal)。这种发出是没有目的的,类似广播。如果有对象对这个信号感兴趣,它就会使用连接(connect)函数,意思是,将想要处理的信号和自己的一个函数(称为槽(slot))绑定来处理这个信号。也就是说,当信号发出时,被连接的槽函数会自动被回调。这就类似观察者模式:当发生了感兴趣的事件,某一个操作就会被自动触发。

1.1 信号的本质

信号是由于用户对窗口或控件进行了某些操作,导致窗口或控件产生了某个特定事件,这时候Qt对应的窗口类会发出某个信号,以此对用户的挑选做出反应。

因此根据上述的描述我们得到一个结论:信号的本质就是事件,比如:

  • 按钮单击、双击
  • 窗口刷新
  • 鼠标移动、鼠标按下、鼠标释放
  • 键盘输入

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

  • 我们对哪个窗口进行操作, 哪个窗口就可以捕捉到这些被触发的事件。
  • 对于使用者来说触发了一个事件我们就可以得到Qt框架给我们发出的某个特定信号。
  • 信号的呈现形式就是函数, 也就是说某个事件产生了, Qt框架就会调用某个对应的信号函数, 通知使用者。

在QT中信号的发出者是某个实例化的类对象,对象内部可以进行相关事件的检测。

1.2 槽的本质

在Qt中槽函数是一类特殊的功能的函数,在编码过程中也可以作为类的普通成员函数来使用。之所以称之为槽函数是因为它们还有一个职责就是对Qt框架中产生的信号进行处理。

举个简单的例子:

女朋友说:“我肚子饿了!”,于是我带她去吃饭。

上边例子中相当于女朋友发出了一个信号, 我收到了信号并其将其处理掉了。

  • 女朋友 -> 发送信号的对象, 信号内容: 我饿了
  • 我 -> 接收信号的对象并且处理掉了这个信号, 处理动作: 带她去吃饭

在Qt中槽函数的所有者也是某个类的实例对象。

1.3 信号和槽的关系

在Qt中信号和槽函数都是独立的个体,本身没有任何联系,但是由于某种特性需求我们可以将二者连接到一起,相当于一个绑定,在Qt中我们需要使用QOjbect类中的connect函数进二者的关联。

QMetaObject::Connection QObject::connect(
    	const QObject *sender, PointerToMemberFunction signal, 
        const QObject *receiver, PointerToMemberFunction method, 
		Qt::ConnectionType type = Qt::AutoConnection);
- 参数:
	- sender: 发出信号的对象
	- signal: 属于sender对象, 信号是一个函数, 这个参数的类型是函数指针, 信号函数地址
    - receiver: 信号接收者
	- method: 属于receiver对象, 当检测到sender发出了signal信号, 
              receiver对象调用method方法,信号发出之后的处理动作
                  
// connect函数相对于做了信号处理动作的注册
// 调用conenct函数的sender对象的信号并没有产生, 因此receiver对象的method也不会被调用
// method槽函数本质是一个回调函数, 调用的时机是信号产生之后, 调用是Qt框架来执行的
// connect中的sender和recever两个指针必须被实例化了, 否则conenct不会成功
connect(const QObject *sender, &QObject::signal, 
        const QObject *receiver, &QObject::method);

1.4 通过实例加深理解

现在要实现一个简单的功能,就说创建一个按钮,点击这个按钮关闭窗口

然后思考,这个功能的信号发出者,信号接受者,以及发出什么信号,接受信号后怎么做

  • 按钮: 信号发出者 -> QPushButton
  • 窗口: 信号的接收者和处理者 -> QWidget
  • 发出信号:被点击 -> clicked
  • 槽函数,即如何处理 -> close

现在我们来实现一下

在ui中添加一个button,取名为closeBtn

 

然后再Mainwindow.cpp 文件中

#include "mainwindow.h"
#include "ui_mainwindow.h"

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

    connect(ui->closeBtn,&QPushButton::clicked,this,&MainWindow::close);
}

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

注意这条语句
connect(ui->closeBtn,&QPushButton::clicked,this,&MainWindow::close);
通过这条语句来实现绑定

现在我们来运行一下

 点击按钮,窗口关闭

本文福利,费领取Qt开发学习资料包、技术视频,内容包括(C++语言基础,C++设计模式,Qt编程入门,QT信号与槽机制,QT界面开发-图像绘制,QT网络,QT数据库编程,QT项目实战,QSS,OpenCV,Quick模块,面试题等等)↓↓↓↓↓↓见下面↓↓文章底部点击费领取↓↓

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

什么是Qt信号槽机制 的相关文章

  • 访问私人成员[关闭]

    Closed 这个问题是基于意见的 help closed questions 目前不接受答案 通过将类的私有成员转换为 void 指针 然后转换为结构来访问类的私有成员是否合适 我认为我无权修改包含我需要访问的数据成员的类 如果不道德 我
  • 是否可以强制 XMLWriter 将元素写入单引号中?

    这是我的代码 var ptFirstName tboxFirstName Text writer WriteAttributeString first ptFirstName 请注意 即使我使用 ptFirstName 也会以双引号结束 p
  • C# 和 Javascript SHA256 哈希的代码示例

    我有一个在服务器端运行的 C 算法 它对 Base64 编码的字符串进行哈希处理 byte salt Convert FromBase64String serverSalt Step 1 SHA256Managed sha256 new S
  • 获取按下的按钮的返回值

    我有一个在特定事件中弹出的表单 它从数组中提取按钮并将标签值设置为特定值 因此 如果您要按下或单击此按钮 该函数应返回标签值 我怎样才能做到这一点 我如何知道点击了哪个按钮 此时代码返回 DialogResult 但我想从函数返回 Tag
  • linux perf:如何解释和查找热点

    我尝试了linux perf https perf wiki kernel org index php Main Page今天很实用 但在解释其结果时遇到了困难 我习惯了 valgrind 的 callgrind 这当然是与基于采样的 pe
  • QML 连接:不推荐使用连接中隐式定义的 onFoo 属性

    升级到 Qt 5 15 时收到以下错误消息 QML Connections Implicitly defined onFoo properties in Connections are deprecated Use this syntax
  • Newtonsoft JSON PreserveReferences处理自定义等于用法

    我目前在使用 Newtonsoft Json 时遇到一些问题 我想要的很简单 将要序列化的对象与所有属性和子属性进行比较以确保相等 我现在尝试创建自己的 EqualityComparer 但它仅与父对象的属性进行比较 另外 我尝试编写自己的
  • 指针问题(仅在发布版本中)

    不确定如何描述这一点 但我在这里 由于某种原因 当尝试创建我的游戏的发布版本进行测试时 它的敌人创建方面不起作用 Enemies e level1 3 e level1 0 Enemies sdlLib 500 2 3 128 250 32
  • 如果使用 SingleOrDefault() 并在数字列表中搜索不在列表中的数字,如何返回 null?

    使用查询正数列表时SingleOrDefault 当在列表中找不到数字时 如何返回 null 或像 1 这样的自定义值 而不是类型的默认值 在本例中为 0 你可以使用 var first theIntegers Cast
  • Qt moc 在头文件中实现?

    是否可以告诉 Qt MOC 我想声明该类并在单个文件中实现它 而不是将它们拆分为 h 和 cpp 文件 如果要在 cpp 文件中声明并实现 QObject 子类 则必须手动包含 moc 文件 例如 文件main cpp struct Sub
  • 在数据库中搜索时忽略空文本框

    此代码能够搜索数据并将其加载到DataGridView基于搜索表单文本框中提供的值 如果我将任何文本框留空 则不会有搜索结果 因为 SQL 查询是用 AND 组合的 如何在搜索 从 SQL 查询或 C 代码 时忽略空文本框 private
  • 从路径中获取文件夹名称

    我有一些路c server folderName1 another name something another folder 我如何从那里提取最后一个文件夹名称 我尝试了几件事 但没有成功 我只是不想寻找最后的 然后就去休息了 Thank
  • 将自定义元数据添加到 jpeg 文件

    我正在开发一个图像处理项目 C 我需要在处理完成后将自定义元数据写入 jpeg 文件 我怎样才能做到这一点 有没有可用的图书馆可以做到这一点 如果您正在谈论 EXIF 元数据 您可能需要查看exiv2 http www exiv2 org
  • 如何衡量两个字符串之间的相似度? [关闭]

    Closed 这个问题需要多问focused help closed questions 目前不接受答案 给定两个字符串text1 and text2 public SOMEUSABLERETURNTYPE Compare string t
  • 如何将单个 char 转换为 int [重复]

    这个问题在这里已经有答案了 我有一串数字 例如 123456789 我需要提取它们中的每一个以在计算中使用它们 我当然可以通过索引访问每个字符 但是如何将其转换为 int 我研究过 atoi 但它需要一个字符串作为参数 因此 我必须将每个字
  • Qt表格小部件,删除行的按钮

    我有一个 QTableWidget 对于所有行 我将一列的 setCellWidget 设置为按钮 我想将此按钮连接到删除该行的函数 我尝试了这段代码 它不起作用 因为如果我只是单击按钮 我不会将当前行设置为按钮的行 ui gt table
  • Process.Start 阻塞

    我正在调用 Process Start 但它会阻止当前线程 pInfo new ProcessStartInfo C Windows notepad exe Start process mProcess new Process mProce
  • mysql-connector-c++ - “get_driver_instance”不是“sql::mysql”的成员

    我是 C 的初学者 我认为学习的唯一方法就是接触一些代码 我正在尝试构建一个连接到 mysql 数据库的程序 我在 Linux 上使用 g 没有想法 我运行 make 这是我的错误 hello cpp 38 error get driver
  • ASP.NET MVC 6 (ASP.NET 5) 中的 Application_PreSendRequestHeaders 和 Application_BeginRequest

    如何在 ASP NET 5 MVC6 中使用这些方法 在 MVC5 中 我在 Global asax 中使用了它 现在呢 也许是入门班 protected void Application PreSendRequestHeaders obj
  • C 中的异或运算符

    在进行按位操作时 我在确定何时使用 XOR 运算符时遇到一些困难 按位与和或非常简单 当您想要屏蔽位时 请使用按位 AND 常见用例是 IP 寻址和子网掩码 当您想要打开位时 请使用包含或 然而 XOR 总是让我明白 我觉得如果在面试中被问

随机推荐

  • Hyperf数据库批量更新

    Hyperf没有批量更新的功能 网上的支持也比较少 但Hyperf是基于laravel的orm 因此可以搜下大神们写的laravel的批量更新的方法 批量更新 public function updateBatch multipleData
  • C语言:定时器原理

    首先 要知道 C语言的定时器是对运行结果起到延时作用 其中 定时单位位毫秒 定时器 顾名思义 肯定会用到时间的 所以 获取时间我们就要用到time库 所以要引用头文件
  • 使用js实现网页录音并上传服务器

    不多嘚嘚 直接上代码
  • Unity界面插件NGUI核心组件说明

    UICamera 可以添加到任何相机 包含事件系统 UICamera是每个UI的重要组成部分 它负责发送Camera中所有NGUI的活动 如果场景中仅有一个Camera 要确保它附有UICamera脚本 如果有多个相机 确保至少用来渲染UI
  • Elasticsearch 7 插件

    1 elasticsearch head 可视化插件 通过浏览器就能看到es的集群部署 节点 索引等信息 注意 es在5 x版本就不再支持head插件安装了 百度搜索可以有多种方式安装 我这里用的是谷歌浏览器安装es head的扩展程序 如
  • 读《携程异步消息系统实践》之总结

    读 携程异步消息系统实践 之总结 消息系统 批量 insertOnly 索引 消息投递 Partition Stick 写入事件截获 预期 Long polling 集群管理 Lease
  • Markdown 有序列表、无序列表中插入代码块

    问题描述 在列表中插入代码块 代码块总是顶格的 并且导致代码块之后的文本也是顶格的 也就是代码块的插入导致了列表的结束 如下所示 解决方法 代码块上方空出来一行 代码块左侧加8个空格或2个TAB 每一行都加 预期效果 扩展 本人个人网站上采
  • 基于Qt仿QQ效果实现图片查看器(支持查看GIF)

    主要提供两个类 第一个类显示静态图片 第二个类显示动态图片 两个类都包含图片缩小放大以及图片移动功能 最后自己封装一个类 根据判断图片是动态还是静态去调用对应的类显示图片 效果展示 判断图片类型 int showImage getImage
  • Mac系统安装Myeclipse2015CI出现虚拟内存为0的问题

    出处 http bbs feng com read htm tid 8450072 page 2 html 方法1 你可以按照9楼的朋友的方法 开启虚拟机的情况下 再安装Myeclipse 就不会出现虚拟内存为0的提示 方法2 Downlo
  • 一元二元三元表达式_2020年高考复习不等式专题训练2.三元不等式的证明

    三元不等式是二元不等式的补充形式 三元不等式和二元不等式类似 经常会有一个三元等式作为条件 解决三元不等式问题的思路大致分为两种 第一是根据等式条件减少未知量的数量 将三元转化为二元 第二是直接利用二元基本不等式的扩展形式或者将三元两两组合
  • Qt中click事件如何响应带参槽函数

    include qttest008 h include
  • Android LCD(一):LCD基本原理篇

    关键词 android LCD TFT 液晶 偏光片 彩色滤光片 背光 平台信息 内核 linux2 6 linux3 0系统 android android4 0 平台 samsung exynos 4210 exynos 4412 ex
  • PHP分页页面重复,WordPress分页标题重复如何解决

    WordPress是一款非常流行的博客程序 虽然它各方面的优化都做的不错了 但每个人的喜好都不一样 一些细节还是可以改进的 No牛网就碰到Wordpress很多的问题都不是那么好实现 毕竟不是专门做CMS的 如等下要说到的Wordpress
  • 【C++】STL库set容器

    STL库set容器 1 构造函数 2 增 2 1 insert 去重 排序 2 2 emplace 去重 排序 2 3 代码演示 3 删 3 1 erase 函数 3 1 1 erase list与vector 3 1 2 erase ma
  • 【python基础知识】20.“午饭吃什么”的python实现(产品思维-实操篇)

    文章目录 前言 练习介绍 练习目标 练习要求 项目实操 明确目标 形成技术方案 编写程序代码 数据准备 主流程逻辑搭建 完善补充确实的功能 最终代码整合 总结 前言 首先 我们回顾以下运用学到的编程知识去做一个产品的大致步骤 同时 也学了一
  • 使配置的环境变量生效

    在dos窗口中输入 set PATH C 之后 关闭该窗口 再次打开窗口 输入 echo PATH 可见配置的环境变量已经生效
  • c#中代码中多线程动态创建progressbar的实例,概念很重要可扩展很多类似概念

    以下是代码中创建progressbar的实例 int count 0 private void button4 Click object sender EventArgs e Thread th new Thread gt Form for
  • Markdown笔记:写数学公式方法

    Markdown笔记 写数学公式方法 这里简单记录一下在markdown中书写数学公式的方法 就像Stackoverflow上的经常有的挺漂亮的公式 其生成的不是图片 而MathJax引擎 在Markdown中添加MathJax引擎也很简单
  • vue项目如何运行(超详图解)

    vue项目如何运行 超详图解 1 查看node npm版本 打开cmd 输入npm v 查看npm版本 输入node v 查看node版本 若出现类似下图显示 即为安装成功 2 删除删除package lock json和node modu
  • 什么是Qt信号槽机制

    1 信号和槽概述 信号槽是 Qt 框架引以为豪的机制之一 所谓信号槽 实际就是观察者模式 发布 订阅模式 当某个 事件 发生之后 比如 按钮检测到自己被点击了一下 它就会发出一个信号 signal 这种发出是没有目的的 类似广播 如果有对象