c++模拟qt信号槽机制
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信号槽机制相关推荐
- Qt信号槽机制-传递自定义数据类型(qRegisterMetaType)
Qt信号槽机制-传递自定义数据类型qRegisterMetaType 前言 前言 通过Qt内置的数据类型进行信号与槽参数传递很方便:如果是自己定义的类型如果想使用signal/slot来传递的话,则没 ...
- Hello Qt——Qt信号槽机制源码解析
基于Qt4.8.6版本 一.信号槽机制的原理 1.信号槽简介 信号槽是观察者模式的一种实现,特性如下: A.一个信号就是一个能够被观察的事件,或者至少是事件已经发生的一种通知: B.一个槽就是一个观察 ...
- c++实现Qt信号槽机制
信号槽机制的原理 信号槽是观察者模式的一种实现,或者说是一种升华: 一个信号就是一个能够被观察的事件,或者至少是事件已经发生的一种通知: 一个槽就是一个观察者,通常就是在被观察的对象发生改变的时候-- ...
- Qt信号槽机制详解及案例
目录 信号槽 标准信号槽 自定义信号槽 信号槽 信号槽是Qt框架引以为豪的机制之一.所谓信号槽,实际就是观察者模式.当某个事件发生之后,比如,按钮检测到自己被点击了一下,它就会发出一个信号(signa ...
- 深入理解Qt信号槽机制
1. 信号和槽概述 > 信号槽是 Qt 框架引以为豪的机制之一.所谓信号槽,实际就是观察者模式(发布-订阅模式).当某个`事件`发生之后,比如,按钮检测到自己被点击了一下,它就会发出一个信号(s ...
- 学习QT之信号槽机制详解
学习QT之信号槽机制详解 一.Qt信号槽机制 概念:信号槽是Qt框架引以为豪的机制之一.所谓信号槽,实际就是观察者模式.当某个事件发生之后,比如:按钮检测到自己被点击了一下,它就会发出一个信号(sig ...
- Qt的信号槽机制介绍(含Qt5与Qt4的差异对比)
转载地址: https://blog.csdn.net/nicai888/article/details/51169520 一 闲谈: 熟悉Window下编程的小伙伴们,对其消息机制并不陌生, 话说: ...
- Qt的信号槽机制介绍
Qt 是一个跨平台的 C++ GUI 应用构架,它提供了丰富的窗口部件集,具有面向对象.易于扩展.真正的组件编程等特点,更为引人注目的是目前 Linux 上最为流行的 KDE 桌面环境就是建立在 Qt ...
- 【QT|趣谈】最详细的信号槽机制介绍!
用最有趣的方式解释信号槽通讯机制 1 导语:信号槽的前世今生 2 QT的信号槽 2.1什么是信号槽? 2.2 用严谨的语言解释信号槽 3 信号槽实战 3.1 信号槽实例 4 信号槽plus 4.1 L ...
最新文章
- 沈向洋博士:三十年科研路,我踩过的那些坑
- 执行python文件报错SyntaxError: Non-ASCII character '\xe8' in file, but no encoding declared
- 征值和特征向量的几何意义、计算及其性质
- 用 XGBoost 做 Learning To Rank
- iOS之播放音效(AVFoundation)
- linux的进程命令,Linux基础进程命令详解
- 使用系统调用pipe建立一条管道线_使用Unixbench对服务器综合性能打分及测试结果...
- 微课|中学生可以这样学Python(例4.7):定时器
- java学习文档_阿里技术专家带你玩转JVM,从底层源码到项目实战,都在这份文档里...
- Net::OpenSSH 模块使用实例
- C#正则表达式判断字符串中是否有数…
- 浅析Windows计算机中丢失SETUPAPI.dll的问题
- php在html中if,html里的if注释怎么使用
- Vscode ssh远程连接失败解决办法
- Failed to resolve: support-core-ui和Failed to resolve: runtime
- 【中南林业科技大学】【陈】第十周作业sqi成绩管理系统
- 51nod 1272 最大距离 By Assassin
- 初识智遥工作流软件——表单开发篇2
- SpringBoot18:集成SpringSecurity
- hazelcast java_Hazelcast入门教程