feat: signal and slot principles; and moc principles (what is done)

signal 和 slot 原理;以及 moc 原理(做了什么内容)
This commit is contained in:
xmuli 2021-03-26 16:22:47 +08:00
parent 8bc8b0b039
commit f9e224204d
6 changed files with 141 additions and 4 deletions

View File

@ -3,4 +3,4 @@ project(DbSigSlot)
set(CMAKE_CXX_STANDARD 14) set(CMAKE_CXX_STANDARD 14)
add_executable(DbSigSlot main.cpp object.cpp object.h) add_executable(DbSigSlot main.cpp object.cpp object.h db_object.cpp)

29
DbSigSlot/db_object.cpp Normal file
View File

@ -0,0 +1,29 @@
#include "object.h"
//db_object: 是由 moc 编译器 将 object.cpp 展开的内容(此处手写表示)
const char sig_names[] = "sig1()";
const char slot_names[] = "slot1()";
MetaObject Object::meta = {sig_names, slot_names};
void Object::sig1()
{
MetaObject::active(this, 0);
}
void Object::slot1()
{
cout << "-----------> this is slot1()";
}
// 槽的索引==> 槽函数
void Object::metacall(int idx)
{
switch (idx) {
case 0:
slot1();
break;
default:
break;
}
}

View File

@ -1,8 +1,19 @@
#include <iostream> #include <iostream>
#include "object.h"
using namespace std; using namespace std;
// 目的:自行构造 moc 编译器,手动将 object.h --> db_bject.cpp (宏 和 moc 编译器处理的部分)
// 时间2021-003-26
// 作者:偕臧 ifmet.cn
// 下载https://github.com/xmuli/QtExamples
// 参考https://blog.csdn.net/perfectguyipeng/article/details/78082360
int main(int argc, char *argv[]) int main(int argc, char *argv[])
{ {
Object *obj1 = new Object();
Object *obj2 = new Object();
Object::db_connet(obj1, "sig1()", obj2, "slot1()");
obj1->testSignal();
return 0; return 0;
} }

View File

@ -1,6 +1,56 @@
#include "object.h" #include "object.h"
#include <cstring>
static int findSignalIndex(const char *str, const char *subStr)
{
if (!str || !subStr || strlen(str) < strlen(subStr))
return -1;
int ret = strcmp(str, subStr);
if (ret == 0)
return ret;
else
return -1;
}
void Object::db_connet(Object *sender, const char *sig, Object *receiver, const char *slot)
{
int sig_idx = findSignalIndex(sender->meta.sig_names, sig);
int slot_idx = findSignalIndex(receiver->meta.slot_names, slot);
if (sig_idx == -1 || slot_idx == -1) {
cout<<"signal or slot not found!";
return;
} else {
Connection c = {receiver, slot_idx};
sender->connectionsMap.insert(pair<int, Connection>(sig_idx, c)); // connectionsMap 私有成员
}
}
void Object::testSignal()
{
db_emit sig1();
}
Object::Object() Object::Object()
{ {
} }
Object::~Object()
{
}
// 通过 sender 的信号 idx ==> 槽函数
void MetaObject::active(Object *sender, int idx)
{
pair<ConnectionMapIt, ConnectionMapIt> ret;
ret = sender->connectionsMap.equal_range(idx); // 寻找[idx, )
for (ConnectionMapIt it = ret.first; it != ret.second; ++it) {
Connection c = (*it).second;
c.recviver->metacall(idx);
}
}

View File

@ -1,11 +1,56 @@
#ifndef OBJECT_H #ifndef OBJECT_H
#define OBJECT_H #define OBJECT_H
#include <iostream>
#include <map>
using namespace std;
#define db_signals protected
#define db_slots
#define db_emit
class Object;
struct MetaObject // 元对象
{
const char *sig_names;
const char *slot_names;
static void active(Object *sender, int idx);
};
struct Connection
{
Object *recviver;
int method;
};
typedef multimap<int, Connection> ConnectionMap;
typedef multimap<int, Connection>::iterator ConnectionMapIt;
class Object class Object
{ {
static MetaObject meta;
void metacall(int idx);
public:
static void db_connet(Object *sender, const char *sig, Object *receiver, const char *slot);
void testSignal();
public: public:
Object(); Object();
virtual ~Object();
db_signals:
void sig1();
// void sig2();
public db_slots:
void slot1();
// void slot2();
friend class MetaObject;
private:
ConnectionMap connectionsMap;
}; };
#endif // OBJECT_H #endif // OBJECT_H

View File

@ -156,10 +156,10 @@
- [QtCreator设置代码美化 astyle 之 Artistic](https://blog.csdn.net/qq_33154343/article/details/101397429) - [QtCreator设置代码美化 astyle 之 Artistic](https://blog.csdn.net/qq_33154343/article/details/101397429)
- [Qt Creator 关闭.cpp文件右侧的黄色警告](https://blog.csdn.net/qq_33154343/article/details/102943623) - [Qt Creator 关闭.cpp文件右侧的黄色警告](https://blog.csdn.net/qq_33154343/article/details/102943623)
- [小技巧Design设计师里无法拖拽action到toolbar里](https://blog.csdn.net/qq_33154343/article/details/100168170) - [小技巧Design设计师里无法拖拽action到toolbar里](https://blog.csdn.net/qq_33154343/article/details/100168170)
- [小技巧:设置`QToolBox`的每一页page的使用单独的布局`QTabWidget`同理)](https://blog.csdn.net/qq_33154343/article/details/100185025) - [小技巧:设置`QToolBox`的每一页page的使用单独的布局`QTabWidget`同理)](https://blog.csdn.net/qq_33154343/article/details/100185025)
- [小技巧QtCreator用快捷键秒实现声明在基类中重写的派生类(纯)虚函数](https://blog.csdn.net/qq_33154343/article/details/104457739) - [小技巧QtCreator用快捷键秒实现声明在基类中重写的派生类(纯)虚函数](https://blog.csdn.net/qq_33154343/article/details/104457739)
- [VS2019调试Qt5时QString显示为内存地址而非字符串](https://xmuli.blog.csdn.net/article/details/116244865)
<br> <br>
@ -172,6 +172,7 @@
- [如何给上游 Qt 提交 Bug 反馈和贡献代码 PATCH](https://xmuli.blog.csdn.net/article/details/107220867) - [如何给上游 Qt 提交 Bug 反馈和贡献代码 PATCH](https://xmuli.blog.csdn.net/article/details/107220867)
- [Qt 项目用 doxygen 生成 .qch嵌入文档到 Assistants](https://xmuli.blog.csdn.net/article/details/114580630) - [Qt 项目用 doxygen 生成 .qch嵌入文档到 Assistants](https://xmuli.blog.csdn.net/article/details/114580630)
- [修改 Doxygen 主题,生成 Qt 风格的文档](https://xmuli.blog.csdn.net/article/details/114591725) - [修改 Doxygen 主题,生成 Qt 风格的文档](https://xmuli.blog.csdn.net/article/details/114591725)
- [QtCreator 中自定义项目例子置于“欢迎-实例”中](https://xmuli.blog.csdn.net/article/details/115049715)
<br> <br>
@ -181,6 +182,7 @@
- [Qt 项目(Cmake)设置国际化支持](https://xmuli.blog.csdn.net/article/details/114439385) - [Qt 项目(Cmake)设置国际化支持](https://xmuli.blog.csdn.net/article/details/114439385)
- [如何构建 QT55.15](https://xmuli.blog.csdn.net/article/details/114259155) - [如何构建 QT55.15](https://xmuli.blog.csdn.net/article/details/114259155)
- [在 Mac 编译成功运行 qt5.15 源码debug 和 release 版本](https://xmuli.blog.csdn.net/article/details/114259186) - [在 Mac 编译成功运行 qt5.15 源码debug 和 release 版本](https://xmuli.blog.csdn.net/article/details/114259186)
- [Qt 信号和槽原理分析](https://xmuli.blog.csdn.net/article/details/115305903)
<br> <br>
@ -252,7 +254,7 @@
## 作者: ## 作者:
[ | xmuli ](https://ifmet.cn) [ | xmuli ](https://ifmet.cn)
<br> <br>