Qt之回调函数:6 在QT中使用回调函数替代信号槽

2023-10-27

在QT中使用回调函数替代信号槽

前面讲了一堆,就是为了实现看到的这篇文章中的例子。由于对回调不懂,前前后后翻阅参考了一大堆优秀的博文,学了不少东西,可是。。。。哎,效果不理想,没信号槽快、稳定。

在QT中使用回调函数替代信号槽

一、前言

​ 在Qt中传数据,我们使用了一个信号和槽系统,但这并不意味着不能使用旧的经过验证的方法,即使用 CallBack回调函数功能。
​ 事实上使用 CallBack 功能比信号和槽要快一些。并且当发送信号的对象在程序中被销毁并且不再使用时,信号理想地从槽中分离而言,回调可以更容易使用。


二、如何使用CALLBACK工作

​ 假设A类包含B类的对象,B类有动作时想要通知到A类,B类应该有个设置回调函数的接口,A类应该定义相应的回调函数,将函数指针传递给B。

还是直接举例吧:
例如,将使用一个类,在图形场景中绘制一个正方形,并由W,A,S,D键控制。移动时,正方形必须将其坐标的数据发送到创建它的类。也就是说,它应该把这个类的函数作为它的 CallBack 函数。要做的程序效果如下,通过WASD控制方块移动,主窗口接收正方形的位置信息,并将位置信息填入QLineEdit:

这里写图片描述


程序及解释

小方块

Square.h

#pragma once

#include <QFrame>
#include <QKeyEvent>

typedef std::function<void(QPointF)> CallBack ;

class Square : public QFrame
{
    Q_OBJECT
public:
    explicit Square(QWidget *parent = nullptr);
    // 设置回调函数的函数
    void setCallbackFunc(CallBack fun);
protected:
    void keyPressEvent(QKeyEvent *e) override;

signals:
    void moved(QPointF point);
private:
    CallBack m_func;
};

Square.cpp

#include "Square.h"
#include "DebugTool.h"
#include <QPointF>
#include <QTime>
#include <QTimer>
Square::Square(QWidget* parent)
    : QFrame(parent)
{
    setAttribute(Qt::WA_StyledBackground);
    setFocusPolicy(Qt::StrongFocus);
}


// 注册回调函数
void Square::setCallbackFunc(CallBack func)
{
    m_func = func;
}

void Square::keyPressEvent(QKeyEvent* e)
{
    QPoint point = this->pos();

    int key = e->key();
    if (key == Qt::Key_W)
        point += QPoint(0, -2);
    if (key == Qt::Key_A)
        point += QPoint(-2, 0);
    if (key == Qt::Key_S)
        point += QPoint(0, 2);
    if (key == Qt::Key_D)
        point += QPoint(2, 0);
    //    cout << QTime::currentTime ();
    //    m_func(this->pos ());

    this->move(point);
    //    emit moved(point);    // 传统的信号槽
    m_func(point);      // 调用回调函数
}

主窗口

MainWindow.h

#pragma once

#include "Square.h"

#include <QMainWindow>

QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACE

class MainWindow : public QMainWindow
{
    Q_OBJECT

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

private:
    Ui::MainWindow *ui;
    Square *m_square;           // 声明正方形 传输回调
    // 声明一个回调函数
    void getPosition(QPointF point);
};

MainWindow.cpp

#include "MainWindow.h"
#include "ui_MainWindow.h"
#include "DebugTool.h"

#include <QTime>
MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    m_square = ui->square;
    CallBack func;
    func = std::bind(&MainWindow::getPosition,this,std::placeholders::_1);
    m_square->setCallbackFunc (func);
    ui->square->setFocus ();
    connect (ui->square,&Square::moved,this,&MainWindow::getPosition );
    getPosition (ui->square->pos ());
}

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

void MainWindow::getPosition(QPointF point)
{
//    cout << QTime::currentTime();
    ui->edt_x->setText (QString::number (point.x ()));
    ui->edt_y->setText (QString::number (point.y ()));
}

MainWindow.ui

界面简化了,没有使用Graphics View 框架

image-20210528214333124

<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
 <class>MainWindow</class>
 <widget class="QMainWindow" name="MainWindow">
  <property name="geometry">
   <rect>
    <x>0</x>
    <y>0</y>
    <width>800</width>
    <height>600</height>
   </rect>
  </property>
  <property name="windowTitle">
   <string>MainWindow</string>
  </property>
  <widget class="QWidget" name="centralwidget">
   <layout class="QGridLayout" name="gridLayout">
    <item row="0" column="0">
     <widget class="QLineEdit" name="edt_x"/>
    </item>
    <item row="0" column="1">
     <widget class="QLineEdit" name="edt_y"/>
    </item>
    <item row="1" column="0" colspan="2">
     <widget class="QWidget" name="widget" native="true">
      <property name="styleSheet">
       <string notr="true">border:1px solid black;</string>
      </property>
      <widget class="Square" name="square">
       <property name="geometry">
        <rect>
         <x>280</x>
         <y>120</y>
         <width>100</width>
         <height>100</height>
        </rect>
       </property>
       <property name="styleSheet">
        <string notr="true">background-color: rgb(85, 255, 0);</string>
       </property>
       <property name="frameShape">
        <enum>QFrame::NoFrame</enum>
       </property>
       <property name="frameShadow">
        <enum>QFrame::Raised</enum>
       </property>
      </widget>
     </widget>
    </item>
   </layout>
  </widget>
  <widget class="QMenuBar" name="menubar">
   <property name="geometry">
    <rect>
     <x>0</x>
     <y>0</y>
     <width>800</width>
     <height>26</height>
    </rect>
   </property>
  </widget>
  <widget class="QStatusBar" name="statusbar"/>
 </widget>
 <customwidgets>
  <customwidget>
   <class>Square</class>
   <extends>QFrame</extends>
   <header location="global">Square.h</header>
   <container>1</container>
  </customwidget>
 </customwidgets>
 <resources/>
 <connections/>
</ui>

总结

使用 std::function< T > 和 std::bind( ) 后,结果发现居然还没有信号槽快。

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

Qt之回调函数:6 在QT中使用回调函数替代信号槽 的相关文章

  • 经纬度正则表达式

    经度 180 0 180 0 整数部分为0 180 输入1到8位小数 0 d 1 8 1 9 d d 1 8 1 0 7 d 1 d 1 8 180 0 1 8 纬度 90 0 90 0 整数部分为0 90 输入1到8位小数 0 1 8 d
  • ant上传组件upload,前端读取文件、创建文件

    业务需求是用户上传文件后 还能修改文件内容 最后保存修改后的文件 实现方式 1 前端读取文件内容后显示在代码编辑器中 方便用户修改 2 点保存按钮时 拿到改变的文件内容后 创建新的文件流 提交给后端 这里演示的是JSON文件数据 选择文件
  • 图显系统DRM CRTC完全解析

    目录 CRTC 工作原理和意义 CRTC 模块的初始化和功能 0 引言 DRM 下的 CRTC 代表 RGB 数据管道 从 drm plane 接收像素数据并将其混合到一起 传输给下级显示设备 drm encoder 由 drm displ
  • 原址删除有序数组重复整数

    给定一个有序数组 原址删除重复超过两次的整数 本笔记适合熟悉Python列表list的 coder 翻阅 学习的细节是欢悦的历程 Python 官网 https www python org Free 大咖免费 圣经 教程 python 完
  • Spring中bean创建的生命周期

    1 推断构造方法 2 实例化 3 依赖注入 4 处理Award回调beanFatoryAware 5 初始化前 处理 postConstruct注解 6 初始化 处理iniyializingBean接口 7 初始化前 进行aop
  • Distributed Database System —— Multi-raft协议介绍

    文章目录 Multi Raft协议 Multi Raft需要解决的问题 Multi Raft实现细节 Cockroach Multi Raft Raft Consistency of Range Replicas Range Leaders
  • SQL备份表数据

    1 情况说明 对某个表 需要进行某些删除或修改操作测试 但也需要数据还原 所以需要备份表中数据 2 思路分析 一般操作 将表A所有的数据 备份到新建表B中 若有其他更屌的操作 请告诉我 万分感谢 3 具体SQL实现 库类型说明 SQL SE
  • Java编程--IO流(Ⅱ 字节流)

    Java编程 IO流 字节流 File类虽然可以操作文件 但是并不是操作文件的内容 若要进行文件内容的操作只能通过两种途径完成 字节流和字符流 若要进行输入及输出操作一般都会按照如下的步骤进行 以文件操作为例 1 通过File类定义一个要操
  • 自定义SonarQube Java规则

    自定义SonarQube扫描Java Rule 在介绍如何自定义规则之前 先介绍一下这几个产品 SonarQube 代码质量管理平台 PMD 源代码分析器 FindBugs Java源代码分析器 查找代码Bug Sonar PMD Sona
  • PhotonServer的使用

    https blog csdn net a962035 article details 80713726
  • 一些编译器与解释器的理解

    概述 在19年拜读完Python解释器以及PHP部分解释器并未完全理解 当时主要关心于几个问题 解释器在干嘛 为什么 怎么干的 导致出现区域性片面的理解 直到今年读到内核才逐渐理解 碰巧看到LLVM 大佬思路就是清晰 简单描述个人的理解 如
  • k8s中的有状态,无状态,pv、pvc等

    数据库是一个典型的有状态服务 他的部署和无状态服务是不一样的 PostgresSQL 基于Kubernetes部署PostgresSQL CSDN博客 一 创建SC PV和PVC存储对象 二 部署PostgresSQL Volume Kub
  • dell进入u盘启动模式_uefi不识别u盘怎么办 uefi不识别u盘方法【图文详解】

    现代的电脑配置更新换代都很频繁 从以前的bios主板到现在的uefi主板配置都有很大的进步 而这种新型uefi配置也给新用户装系统带来麻烦 有些用户用u盘启动盘装系统发现uefi不识别u盘 uefi bios识别不了u盘的原因其实就是Lau
  • layui+poi-Java实现导入导出excel文件

    目录 需求说明 一 实现思路 二 前端代码 1 引入layui 2 隐藏部分内容 1 静态页面代码 2 js jquery 代码 点击 导入xx 按钮的js 弹出上面隐藏的内容 3 效果如下 3 下载模板js 4 选择文件 上传js 三 后
  • STM32USB的枚举过程简介

    STM32的USB枚举过程介绍 之前的说明 文中大量引用网上资料 在文后已给出资料的引用说明 文件涉及到的USB各种传输包各个位的含义以及USB标准设备请求的含义都没有做说明 推荐看 圈圈教你玩USB 里面有详细的说明 一 枚举前的工作 系
  • 034_非关系型数据库Redis_安装配置 & 基础语法 & Python交互

    文章目录 1 认识Redis 2 Redis 安装和配置 3 Redis 数据类型 4 Redis 内置指令 5 Redis 配置文件 远程登陆 6 Redis 应用场景 6 1 Redis 应用 手机手机验证码 6 2 Redis 应用
  • 【系统分析师之路】第七章 复盘系统设计(面向服务开发方法)

    系统分析师之路 第七章 复盘系统设计 面向服务开发方法 复盘系统设计 面向服务开发方法 系统分析师之路 第七章 复盘系统设计 面向服务开发方法 前言部分 历年真题考点分析 1 考点分析 2 重要知识点 第一部分 综合知识历年真题 2008下

随机推荐

  • ucint核心边缘分析_社会网络分析中核心边缘分析的简单教程

    最近碰到一位朋友在留言向我咨询如何用社会网络分析进行核心边缘分析 因此 根据这位朋友提供的数据 简单的操作了一下 并制作成教程 分析了可能存在的问题 教程如下 1 打开软件 2 点击上图表格 通过复制 粘贴输入数据 并保存至某一文件夹 3
  • python 字典

    字典的特征 1 字典中数据必须是以键值对的形式出现的 2 键不能重复 而值可以 3 字典中的键是不能修改的 而值是可以修改的 可以为任何对象 因此键不能用变量 字典的书写范例 dictory 猫 cat 狗 dog 狼 holf print
  • jenkins pipeline之自动构建(gitlab webhook 和 Generic Webhook Trigger集成)

    需求 1 开发在哪个分支上提交代码 jenkins就自动发布相对应的分支 2 实现既能手动发布jenkins 也要实现自动webhook发布 约定 和开发约定分支对应的环境 比如 debug对应开发环境 develop对应测试环境 mast
  • 【Fastdfs】通过 docker 快速搭建集群 fastdfs 环境

    Fastdfs 通过 docker 快速搭建集群 fastdfs 环境 1 镜像构建 码云地址 https gitee com hbsky fastDFS 构建新的镜像 使用我的镜像也行 docker build t registry cn
  • dlink网络打印服务器如何修改ip地址,如何使用脚本更改网络打印机的IP地址?

    HI 大家好 现在的客户端全部基于WIN XP WIN7 都连接着一台HP 4650网络打印机 IP ADDRESS 10 201 0 1 但是最近打印机IP做了整体的调整 如何实现用脚本更改以前的IP呢 我试过以下的脚本 但是只有添加TC
  • keil5中Undefined symbol XXX 的解决方法

    keil5中Undefined symbol XXX 的解决方法 OBJ LED axf Error L6218E Undefined symbol SPI Cmd referred from spi o OBJ LED axf Error
  • 库存预占架构升级方案设计-交易库存中心

    背景介绍 伴随物流行业的迅猛发展 一体化供应链模式的落地 对系统吞吐 系统稳定发出巨大挑战 库存作为供应链的重中之重表现更为明显 近三年数据可以看出 接入商家同比增长37 64 货品种类同比增长53 66 货品数量同比增长46 43 仓库数
  • 人工智能发展情况调研

    人工智能发展情况调研Artificial intelligence development circumstance investigation北京师范大学继续教育学院 2000级计算机科学与技术 赵旭峰E mail zxf95 163 c
  • Excel中如何找出两列数据中相同的数据,并且进行同行显示

    使用VLOOKUP方法即可 VLOOKUP A2 Sheet1 B C 1 0 的含义是 在sheet1工作表的B C区域的首列中查找等于a2的值 找到后 返回该区域的同行的值 最后的参数0表示精确查找 比如 想要列2根据列1中的数据进行排
  • PG概述及OSD对PG状态的影响

    前言 随着分布式存储的广泛应用 目前对PG的关注越来越多 本文基于ONStor分布式存储系统简要介绍一下PG的状态变化 重点说明OSD对PG状态的影响 一 Ceph分布式存储概述 Ceph是一个统一的分布式存储系统 设计初衷是提供较好的性能
  • Gazebo中特异性里程计odom的发布

    需求 将里程计 odom改成以小车初始位置为原点 车体坐标轴为方向建立坐标系 用该坐标系下的位姿作为里程计数据的位姿 分析 odom是ros发布的相对固定的里程计信息 不能使用命令行工具直接修改里程计信息参考的初始位置 因此 从 odom坐
  • QT5 创建“打开文件”按钮

    在GUI界面设计中 有时需要 打开文件 按钮 以加载外部文件 则需要我们用QFileDialog的静态函数完成 QT5中几个文件相关函数如下 函数名 作用 getOpenFileName 加载用户选择文件的文件名 getSaveFileNa
  • Java函数、数组

    Java函数 数组 函数 函数 就是定义在类中的具有特定功能的一段独立小程序 格式 修饰符 返回值类型 函数名 参数类型 参数1 参数类型 参数2 执行语句 return 返回值 返回值类型 函数运行后的结果的数据类型 参数类型 是形式参数
  • 手撸代码-删除链表的倒数第n个节点

    描述 给定一个链表 删除链表的倒数第 nn 个节点并返回链表的头指针 例如 给出的链表为 1 2 3 4 5 n 2n 2 删除了链表的倒数第 n 个节点之后 链表变为1 2 3 5 备注 题目保证 nn 一定是有效的 请给出时间复杂度为
  • Centos下配置Harbor私有仓库

    Centos下配置Harbor私有仓库 Harbor是一个开源的企业级容器镜像仓库 可以帮助用户建立和管理自己的私有Docker镜像仓库 本文将介绍在Centos操作系统下如何配置和使用Harbor私有仓库 安装Docker 首先 我们需要
  • 服务器安装完系统老重启,服务器老是自动重启

    服务器老是自动重启 内容精选 换一换 该任务以 Windows Server 2008 R2 64位 操作系统为例 指导用户安装Windows操作系统 由于镜像文件不同 安装步骤稍有不同 请根据实际的安装界面提示进行操作 请根据实际情况完成
  • linux文件系统初始化过程(3)---加载initrd(上)

    一 目的 本文主要讲述linux3 10文件系统初始化过程的第二阶段 加载initrd initrd是一个临时文件系统 由bootload负责加载到内存中 里面包含了基本的可执行程序和驱动程序 在linux初始化的初级阶段 它提供了一个基本
  • 如何在Linux中设置静态IP和配置网络

    如何在Linux中设置静态IP和配置网络 文章目录 如何在Linux中设置静态IP和配置网络 1 使用ifconfig的一次性修改 1 修改静态ip 2 修改网关 2 修改配置文件的永久性修改 1 Ubuntu相关系统 2 CentOS相关
  • C#+Sql Server开发一个简易的学生管理系统

    效果图 目前是这样 如果想做成这样 加一个DataGridView进行显示即可 使用VS2017新建一个控制台应用程序 连接数据库 即可对数据库进行增删改查 更多的功能还没有写 不适合直接拿去做课设 不过基本架子都有了 更多复杂的功能写sq
  • Qt之回调函数:6 在QT中使用回调函数替代信号槽

    文章目录 一 前言 二 如何使用CALLBACK工作 程序及解释 小方块 主窗口 MainWindow ui 总结 在QT中使用回调函数替代信号槽 前面讲了一堆 就是为了实现看到的这篇文章中的例子 由于对回调不懂 前前后后翻阅参考了一大堆优