qt的信号槽原理:moc元对象编译器翻译头文件成moc文件,实现头文件中的信号的函数体和申明信号、槽的索引,加上一个qt_static_metacall的函数等等,然后在connect中的QObjectConnectionListVector的容器中添加这样的一个结构体,通过信号索引找到从容器中找到这个结构体,然后从结构体中拿到回调函数,就能找到槽函数。

结构体:
QScopedPointer<QObjectPrivate::Connection> c(new QObjectPrivate::Connection);c->sender = s;c->signal_index = signal_index;c->receiver = r;c->method_relative = method_index;c->method_offset = method_offset;c->connectionType = type;c->isSlotObject = false;c->argumentTypes.store(types);c->nextConnectionList = 0;c->callFunction = callFunction;

从这个原理可以看出实际上是找函数指针的一个过程。
示例模拟:
调用对象:

#include "widget.h"#include <QApplication>
#include "test.h"int main(int argc, char *argv[])
{QApplication a(argc, argv);Test *tmptest = new Test;return a.exec();
}
#ifndef TEST_H
#define TEST_H#include <QtWidgets>class Test
{
public:Test();static void testA(void *val);
};#endif // TEST_H
#include "test.h"
#include "widget.h"void Test::testA(void* val)
{qDebug()<<"funcA test:"<<QString::fromUtf8((char*)val);
}void testB(void)
{qDebug()<<"funcB test";
}Test::Test()
{Widget* tmpw = new Widget;//注册回调函数,类似connect的连接tmpw->register_Func(A,testA); //testA:调用类成员函数,注:必须为静态函数。tmpw->register_Func(B,testB); //testB:调用普通函数tmpw->show();
}

创建回调函数的头文件:

#ifndef WIDGET_H
#define WIDGET_H#include <QWidget>
#include <QtWidgets>
#include <QDebug>enum FunType
{A,B
};QT_BEGIN_NAMESPACE
namespace Ui { class Widget; }
QT_END_NAMESPACEclass Widget : public QWidget
{Q_OBJECTpublic:Widget(QWidget *parent = nullptr);~Widget();//----------------申明位置---------------------begintypedef void(*FuncA)(void*);//该指针*FuncA指向一个返回值为void,参数为void*的函数,FuncA保存这个函数的地址。FuncA Func_actionA; //类似槽函数typedef void(*FuncB)(void);FuncB Func_actionB; //类似槽函数template <typename T>void register_Func(FunType type,T fobj) //类似connect的连接源码{switch (type) {case A:Func_actionA = (FuncA)fobj;break;case B:Func_actionB = (FuncB)fobj;default:break;}}//---------------------------------------------end
private slots:void slottestA();void slottestB();
private:Ui::Widget *ui;QPushButton* m_btn1;QPushButton* m_btn2;
};
#endif // WIDGET_H

创建回调函数的cpp:

#include "widget.h"
#include "ui_widget.h"
#include "test.h"Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget)
{ui->setupUi(this);m_btn1 = new QPushButton("FuncAtest",this);m_btn2 = new QPushButton("FuncBtest",this);QVBoxLayout* lay = new QVBoxLayout(this);lay->addWidget(m_btn1);lay->addWidget(m_btn2);this->setLayout(lay);connect(m_btn1,SIGNAL(clicked()),this,SLOT(slottestA()));connect(m_btn2,SIGNAL(clicked()),this,SLOT(slottestB()));
}Widget::~Widget()
{delete ui;
}void Widget::slottestA()
{QString val = "FuncAtest";Func_actionA(val.toUtf8().data()); //调用位置,类似发信号
}void Widget::slottestB()
{Func_actionB(); //调用位置,类似发信号
}

c++模拟qt信号槽机制相关推荐

  1. Qt信号槽机制-传递自定义数据类型(qRegisterMetaType)

    Qt信号槽机制-传递自定义数据类型qRegisterMetaType 前言 前言 通过Qt内置的数据类型进行信号与槽参数传递很方便:如果是自己定义的类型如果想使用signal/slot来传递的话,则没 ...

  2. Hello Qt——Qt信号槽机制源码解析

    基于Qt4.8.6版本 一.信号槽机制的原理 1.信号槽简介 信号槽是观察者模式的一种实现,特性如下: A.一个信号就是一个能够被观察的事件,或者至少是事件已经发生的一种通知: B.一个槽就是一个观察 ...

  3. c++实现Qt信号槽机制

    信号槽机制的原理 信号槽是观察者模式的一种实现,或者说是一种升华: 一个信号就是一个能够被观察的事件,或者至少是事件已经发生的一种通知: 一个槽就是一个观察者,通常就是在被观察的对象发生改变的时候-- ...

  4. Qt信号槽机制详解及案例

    目录 信号槽 标准信号槽 自定义信号槽 信号槽 信号槽是Qt框架引以为豪的机制之一.所谓信号槽,实际就是观察者模式.当某个事件发生之后,比如,按钮检测到自己被点击了一下,它就会发出一个信号(signa ...

  5. 深入理解Qt信号槽机制

    1. 信号和槽概述 > 信号槽是 Qt 框架引以为豪的机制之一.所谓信号槽,实际就是观察者模式(发布-订阅模式).当某个`事件`发生之后,比如,按钮检测到自己被点击了一下,它就会发出一个信号(s ...

  6. 学习QT之信号槽机制详解

    学习QT之信号槽机制详解 一.Qt信号槽机制 概念:信号槽是Qt框架引以为豪的机制之一.所谓信号槽,实际就是观察者模式.当某个事件发生之后,比如:按钮检测到自己被点击了一下,它就会发出一个信号(sig ...

  7. Qt的信号槽机制介绍(含Qt5与Qt4的差异对比)

    转载地址: https://blog.csdn.net/nicai888/article/details/51169520 一 闲谈: 熟悉Window下编程的小伙伴们,对其消息机制并不陌生, 话说: ...

  8. Qt的信号槽机制介绍

    Qt 是一个跨平台的 C++ GUI 应用构架,它提供了丰富的窗口部件集,具有面向对象.易于扩展.真正的组件编程等特点,更为引人注目的是目前 Linux 上最为流行的 KDE 桌面环境就是建立在 Qt ...

  9. 【QT|趣谈】最详细的信号槽机制介绍!

    用最有趣的方式解释信号槽通讯机制 1 导语:信号槽的前世今生 2 QT的信号槽 2.1什么是信号槽? 2.2 用严谨的语言解释信号槽 3 信号槽实战 3.1 信号槽实例 4 信号槽plus 4.1 L ...

最新文章

  1. 沈向洋博士:三十年科研路,我踩过的那些坑
  2. 执行python文件报错SyntaxError: Non-ASCII character '\xe8' in file, but no encoding declared
  3. 征值和特征向量的几何意义、计算及其性质
  4. 用 XGBoost 做 Learning To Rank
  5. iOS之播放音效(AVFoundation)
  6. linux的进程命令,Linux基础进程命令详解
  7. 使用系统调用pipe建立一条管道线_使用Unixbench对服务器综合性能打分及测试结果...
  8. 微课|中学生可以这样学Python(例4.7):定时器
  9. java学习文档_阿里技术专家带你玩转JVM,从底层源码到项目实战,都在这份文档里...
  10. Net::OpenSSH 模块使用实例
  11. C#正则表达式判断字符串中是否有数…
  12. 浅析Windows计算机中丢失SETUPAPI.dll的问题
  13. php在html中if,html里的if注释怎么使用
  14. Vscode ssh远程连接失败解决办法
  15. Failed to resolve: support-core-ui和Failed to resolve: runtime
  16. 【中南林业科技大学】【陈】第十周作业sqi成绩管理系统
  17. 51nod 1272 最大距离 By Assassin
  18. 初识智遥工作流软件——表单开发篇2
  19. SpringBoot18:集成SpringSecurity
  20. hazelcast java_Hazelcast入门教程

热门文章

  1. Java对象类型向上转型和向下转型
  2. 【笔记】CentOS 6-7 静默安装Oracle11g
  3. R语言标准化死亡率 (SMR)计算(2)
  4. 操作系统 操作系统内核
  5. 贵州省成立农业大数据专家委员会
  6. Element-Plus el-col、el-row快速布局
  7. Nginx的安装配置教程
  8. AVI movi LIST
  9. php redis消息订阅与发布_php+redis 实现发布订阅功能
  10. ShaderForge制作简单特效