QT学习笔记(20) ——回调函数的使用

2023-11-10

前言

因为程序一直有用到这个回调函数,虽然能够大概看得懂,知道是把函数指针从一个类传到另一个类,给这另一个类用,但是,里面具体详细的内容不太明确。在这里,稍微记录一下。

正文

首先,我们先了解一下函数指针是啥东西?

函数指针

定义:指向存放函数空间首地址的指针变量。
解析:函数指针是指向函数的指针变量。 因此“函数指针”本身首先应是指针变量,只不过该指针变量指向函数。这正如用指针变量可指向整型变量、字符型、数组一样,这里是指向函数。如前所述,C在编译时,每一个函数都有一个入口地址,该入口地址就是函数指针所指向的地址。有了指向函数的指针变量后,可用该指针变量调用函数。

回调函数

定义:回调函数就是一个通过函数指针调用的函数。如果你把函数的指针地址作为参数传递给另一个函数,当这个指针被用来调用它所指向的函数的时候,我们就说这是回调函数。

为何要使用回调函数?

  1. 因为有些时候,我们调用函数的时机是:当触发某个特定的事件,这个时候调用你定义的函数。而如果采用一般的方法,你可能需要去用啥信号槽进行一定的监听,监听你所要控制的事件的时机。而用回调函数,就不存在这个问题。你只需要把函数传到对应的函数中,当这个函数执行时,它自然就会调用这个回调函数,从而执行你所需要的功能。
  2. 第二种解释方式:注册回调简单解释就是一个高层调用底层,底层再回过头来调用高层,这个过程就叫注册回调, 连接高层和底层就叫注册回调函数。高层程序C1调用底层程序C2,而在底层程序C2 又调用了高层程序C2的callback函数,那么这个callback函数对于高层程序C1来说就是回调函数。 在设计模式中这个方式叫回调模式。

例子

这篇文章讲了一个例子,值得探讨一下,这应该也是我能想到的回调的一个用处。
比如,我们写A B C D 四个函数,封装成一个库文件,然后我们的主函数里面要写一个功能函数,这个功能要用到函数A,假如不用函数指针,这个功能函数就要调用函数A,下次如果用到函数B,那么我们得删掉A,调用函数B,每次都要修改这个函数很麻烦,但如果使用回调函数就不一样了,我们可以定义4个函数指针,把4个函数的地址分别赋给4个函数指针,然后将函数指针当作参数传递给功能函数,功能函数就可以通过修改参数来调用对应的函数,而它本身不用做任何的修改。这样的话,功能函数就可以根据不同的情况,通过函数指针去调用不同的函数,代码如下:

#include <stdio.h>
#include <stdlib.h>
float ADD(float a, float b)
{
    return a + b;
}

float SUB(float a, float b)
{
    return a - b;
}

float MUL(float a, float b)
{
    return a * b;
}

float DIV(float a, float b)
{
    return a / b;
}

float (*A)(float x, float y) = ADD;
float (*B)(float x, float y) = SUB;
float (*C)(float x, float y) = MUL;
float (*D)(float x, float y) = DIV;

float  fun(float x, float y, float(*p)(float x, float y)) {
     return p(x, y);
}

int main()
{
    printf("%f", fun(2, 3, A));

}
  1. 当使用回调函数时,你就可以利用传入函数的指针去调用在外面那个类的一些函数了。
    给一个比较简单的回调处理函数
//回调处理类
class CSampleCaptureEventHandler : public ICaptureEventHandler
{
public:
void DoOnImageCaptured(CImageDataPointer& objImageDataPointer, void* pUserParam)
{
        MDeviceDahengG3UC* pDev = static_cast<MDeviceDahengG3UC*>(pUserParam);
        pDev->triggerEvent(objImageDataPointer);
}
};

回调对象的声明:CSampleCaptureEventHandler        *m_pCaptureEventHandler;
外面的注册:m_objStreamPtr->RegisterCaptureCallback(m_pCaptureEventHandler,this);

在外面要使用的地方,你只需要注册一下,把那个要传进来的函数的指针传进来就可以了。然后,在这里进行一定的强制类型转换,就可以去调用对应的函数了。当这个指向的函数内部发生特定条件时,这个回调函数就生效了。

注册函数的作用就是告诉底层代码,使用者想让你调用的函数是那个,也就是传进去的指针对应的那个函数。

总结

希望你能耐下心来好好把这些文字看完,也许有些许理解上的偏差,但我觉得大体应该是没错的,值得你花费几分钟去看下来。

参考文献

  1. 注册回调函数(一)
  2. 使用注册回调函数
  3. 回调函数的作用

若有错误,请多指教~

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

QT学习笔记(20) ——回调函数的使用 的相关文章

  • QtWebEngine Quicknano 在嵌入式 Linux 中没有声音

    我已将 QtWebEngine 编译到我的 i MX6 嵌入式设备中 当我尝试使用 Quicknanobrowser 播放 YouTube 视频时 视频会播放 但没有声音 事实上 当我尝试播放音频文件时没有声音hpr dogphilosop
  • 在 Windows 上静默安装 Qt55 Enterprise

    编辑 在 Qt 支持的帮助下 我已经解决了如何自动化 Qt 企业安装程序的这两个部分 下面是脚本调用 我正在尝试在 Windows 8 1 和 Windows 10 上静默安装 Qt 5 5 1 Enterprise 使用 script 开
  • 使用 QTestLib 时抑制 qDebug

    我正在向 Qt 中的项目添加单元测试 并希望使用 QTestLib 我已经设置了测试并且它们运行良好 问题是在项目中我们重写了 qDebug 以输出到我们自己的日志文件 这在运行应用程序时效果很好 问题是当我测试类时 它有时会开始记录 然后
  • 使用样式表时的 QTabWidget tabPosition

    我目前正在使用样式表来设计应用程序的主题 这是我用于 QTabWidget 的样式表 QTabBar et QTabWidget QTabBar tab background qlineargradient spread pad x1 0
  • 如何从 ffmpeg 中打开的文件获取流信息?

    我正在尝试使用 ffmpeg 读取视频文件 我有与其旧版本相对应的工作代码 并开始尝试升级到最新的构建版本 将所有这些已弃用的函数替换为其实际的类似函数 但是我遇到了问题 似乎没有检索到任何流 并且视频负载停止在轨道中 这是我正在使用的代码
  • 在 Qt 中用像素图画笔画一条线?

    一段时间以来 我正在使用 Qt C 开发一个简单的绘图和绘画应用程序 目前我正在使用 QPainter drawLine 进行绘制 并且工作正常 我想做的是用像素图画笔绘图 这是我可以做到的 我可以使用 QPainterPath 和 QPa
  • 将 QMAKE_CXXFLAGS += -std=c++11 添加到 qt 中的 .pro 文件不起作用(在 linux 12.04 上)

    编译器输出 main o 错误 1 cc1plus 错误 无法识别的命令行选项 std c 11 解决方案是更新系统上的旧 gcc 版本 事实上 我很惊讶你的 12 04 Ubuntu 变体上有这么旧的版本 默认情况下应该有 4 6 3 您
  • 如何搭建qtwayland?

    我花了一整天的时间尝试使用QtWayland Compositor 1 0在 Qt 创建者中 我已经遵循了从那里开始的所有步骤https wiki qt io QtWayland https wiki qt io QtWayland但我收到
  • Qt 5.5 QOpenGLWidget 链接错误未链接任何 openGL 调用

    我尝试使用 Qt 5 5 1 构建一个简单的 OpenGL 应用程序 一切都很好 直到我尝试使用 glClearColor 等 openGL 本机函数调用 该小部件实际上编译并产生黑屏 但在我尝试使用任何 openGL 本机函数后 它甚至不
  • 如何在Qt无框窗口中实现QSizeGrip?

    如何使用 Qt 无框窗口实现 QSizeGrip 代码会是什么样的 您只需在布局内窗口的一角添加 QSizeGrip 即可使其保持在该角落 QDialog dialog new QDialog 0 Qt FramelessWindowHin
  • 第一个随机数始终小于其余随机数

    我碰巧注意到 在 C 中 使用 std rand 方法调用的第一个随机数大多数时候都明显小于第二个随机数 关于 Qt 实现 第一个几乎总是小几个数量级 qsrand QTime currentTime msec qDebug lt lt q
  • 如何在qt中进行异步文件io?

    我想知道如何在qt中实现异步文件io 这在普通的 qt 中是否可以实现 或者有人需要使用另一个库 例如 libuv 来实现这样的事情 我正在查看 QDataStream 但即使它是一个 流 它也不是非阻塞的 我想一种解决方案是制作一个在内部
  • 在 Qt 5 中嵌入 Python

    我想将 Python 解释器嵌入到 Qt 5 应用程序中 我在 Qt 5 中有一个工作应用程序 但是当我把 include
  • 如何从浮点数组创建新的 QImage

    我有一个代表图像的浮点数数组 列在前 我想在 QGraphicsSecene 上将图像显示为 QPixmap 为了做到这一点 我尝试使用 QImage 构造函数 QImage const uchar data int width int h
  • 如何在 QT 中绘制点?

    我正在用 QT 用 C 编写一个应用程序 其中有 n 个点并计算它的凸包 然而 一旦计算出来 我不知道如何绘制点并绘制船体的边界 制作菜单按钮等很简单 但我不确定我是否知道执行此操作的工具 你怎么做到这一点 图形视图 addEllipse
  • Qml 和模糊图像

    我想使用 QML 实现模糊效果 我找到了有关 效果 模糊 的参考资料 例子 http qt gitorious org lscunha qt components lscunha qt components blobs d78feec567
  • new 运算符(以及 malloc)无法分配约 450 MB 的内存 [重复]

    这个问题在这里已经有答案了 我正在开发一个程序 该程序在内存中存储大约 2 2 亿个短值的数组 该数据块的分配方式如下 short arrayName new short SIZE OF ARRAY 然后将文件的内容读入内存 在团队中的另一
  • QMutex 是否需要是静态的,以便此类实例的其他线程调用知道暂停其操作?

    从多个线程调用以下附加函数 我不希望数据重写附加 因为计数器尚未增加 除了当前使用 Append 的线程之外 这是否会挂起所有进入的线程 或者其他线程会继续运行而不追加数据吗 互斥锁是否需要是 静态 的 或者每个实例都知道要暂停操作吗 如果
  • QStyledItemDelegate 绘制自定义小部件失败

    在我的一个项目中 我使用的是QTableWidget为了显示一些复杂的计算结果 为了提高表格的可读性 我需要在单个表格单元格内显示两个对齐的值 后来我想通过使用颜色或箭头等来进一步自定义小部件 为此我源自QStyledItemDelegat
  • 获取 QListView 中所有可见项目的简单方法

    我正在尝试使用 Qt Framework 开发一个图像库应用程序 应用程序从所选文件夹加载所有图像 并使用 QListView 控件显示这些图像 但现在我想通过仅加载用户可见的图像来减少内存消耗 由于没有直接函数来获取视图中的所有可见项目

随机推荐

  • FFmpeg推送的流,播放端播放时花屏问题总结

    1 前言 很多次遇到了这种问题 在这里做一下总结 2 问题总结 第一 是播放端读取缓冲区不够 有时候 高清码流 一帧就好几兆 所以缓冲区要足够长 对于基于FFmpeg的播放器 应该是下面的参数 av dict set this gt opt
  • Lunix下软件安装

    1 Tarball 的产生和使用 1 1 make与configure make是能够对文件进行编译的简化指令 通常软件开发商都会写一支文件名为 configure 或者是 config 的侦测程序来侦测用户的作业环境 侦测完毕后主动的建立
  • Arduino:设置ADC参考电压

    使用LM35模组进行温度传感时 忘记设置参考电压 默认使用当前Arduino工作电压作为参考电压 但是 当用不稳定的外部电源供电时 输出值就不准确了 这时 最好使用内部参考电压 看下面的程序 int LM35 A0 void setup p
  • C++11 谈谈shared_ptr

    C 11 谈谈shared ptr 细节 个人用 十分主观 仅供参考 shared ptr是C 11中加入的一种智能指针 其实并不够智能 其作用就是帮助我们管理在堆中开辟的空间 避免野指针等众多内存管理不当造成的问题 重点 智能指针会自动的
  • CentOS7.4中安装了Mysql5.7之后如何查看默认密码

    之前在虚拟机中安装了CentOS7 4 然后在CentOS7 4中安装了Mysql5 7 安装完成后 Mysql没有生成默认密码 所以可以直接使用命令mysql uroot或mysql登录mysql 今天我在腾讯云服务器 操作系统 Cent
  • RGB屏调试经验分享——颜色不对

    本篇博客分享我之前调试RGB888 LCD屏遇到的两个比较麻烦的问题及解决方法 我这里不说怎么调试屏的周期 时间宽度等调试方法 寄存器怎么填 根据LCD数据手册和主控手册挨个对比设置 花点时间应该很容易设置好 分享的两个问题经验 是LCD可
  • 你是如何自学Python的,全网最全Python攻略,看完这一篇就够了

    新手小白学Python在还没有人带的情况下很容易半途而废 首先给大家总结一下我这两年Python的学习 开发经验遇到一些问题 大家首先得正视这些问题 因为超90 的人在初学Python时都会也遇到 自学网上资料多 但质量参差不齐 资料杂乱又
  • 狂神。SMBMS(超市订单管理系统)

    SMBMS 超市订单管理系统 代码 建议把静态资源和sql拿过来用 其他自己写一遍练手 注意修改相关配置文件 链接 https pan baidu com s 12MmpF9msJVjLT1U77XYfRw 提取码 11fv 数据库 项目如
  • 【VUE】自定义全局指令,局部指令

    全局指令 vue项目中一般使用utils文件夹来存放全局的函数 指令 首先在src目录下创建utils文件夹 在文件夹内创建directives js文件 自定义指令 focus 使表单元素获取焦点 export default Vue g
  • sklearn集成方法

    集成方法 集成方法是训练很多基学习器 然后用这些基学习器去对进行分类或者回归 最后取所有结果中比例最大的作为模型的结果 投票分类器 Voting Classifiers 定义 对于一个训练集 有很多分类器 比如说Logistic KNN S
  • 猜数字游戏

    代码 pragma warning disable 4996 include
  • VMware-workstation中文版修改成英文版简单方法

    找到你的VMware安装目录 我的是D VMware Workstation messages 有ja zh CN两个语言包 只需要把zh CN文件夹重命名 或移动保存到其他盘符 再重启VMware 就是英文了 如果要使用中文版则把zh C
  • 数据库远程同步(主服务器不能访问从属服务器)

    数据库远程同步 主服务器不能访问从属服务器 背景 从属服务器能够访问主服务器 主服务器不能访问从属服务器 参考方案 也可以考虑主从服务器 使用mysqldump同步两台服务器中不同数据库相同表结构的表 江湖乄夜雨 博客园 cnblogs c
  • 程序员如何缓解压力,保持心理健康

    说明 下面这篇文章 我觉得作者写的很好 就引用了下来 心理保健 心理保健 心理健康的标准 心理健康的标准 1 对现实的正确认识 看问题能持客观的态度 2 自知 自尊与自我接纳 能现实地评价自己 不过分地显示自己也不刻意地取悦别人 既接纳自己
  • 基于Eclipse的下一代建模工具

    基于Eclipse的下一代建模工具 孟言 CSDN的网友大家下午好 昨天世界杯结束了 今天我们就可以把精力重新投入到我们酷爱的技术上 很高兴与大家进行这一起CSDN的视频节目 我们今天很高兴请到软件建模资深的专家 一位是李纪华 他是IBM
  • qt中实现多语言功能

    qt实现多语言 引言 示例 环境 demo 使项目可以多语言 步骤一 步骤二 步骤三 方式一 方式二 步骤四 附加 引言 在做项目时 有时希望我们的程序可以在不同的国家使用 这样最好的方式是一套程序能适应于多国语言 Qt提供了这样的功能 使
  • 特征提取网络(分类)

    以下网络可通过torchvision models导入 import torchvision models as models resnet18 models resnet18 pretrained True vgg16 models vg
  • 带你用一个更好的方法注释掉一段代码

    今天分享一个好用的注释代码块的方法给大家 话不多说 我们平时常用的注释一句代码和文字就用 或者 如 char a 0 这是一个常用的注释方法 但是我们如果注释一大块内容呢 就会用到上面提到的 了 但是这个方法不适应用于代码块中存在 的情况
  • Windows获取系统、进程CPU占用率、内存、磁盘、网卡

    1 获取系统cpu 使用WindowsAPI函数GetSystemTimes 为获取当前使用率 通过执行两次的方式进行差值比较 在win7 win10上试验结果准确 具体用法参考下列代码 Windows程序获取cpu占用率 void Get
  • QT学习笔记(20) ——回调函数的使用

    目录 前言 正文 函数指针 回调函数 为何要使用回调函数 例子 总结 参考文献 前言 因为程序一直有用到这个回调函数 虽然能够大概看得懂 知道是把函数指针从一个类传到另一个类 给这另一个类用 但是 里面具体详细的内容不太明确 在这里 稍微记