From f9e224204d9498307a53d4e771de76e758f28c52 Mon Sep 17 00:00:00 2001 From: xmuli Date: Fri, 26 Mar 2021 16:22:47 +0800 Subject: [PATCH] feat: signal and slot principles; and moc principles (what is done) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit signal 和 slot 原理;以及 moc 原理(做了什么内容) --- DbSigSlot/CMakeLists.txt | 2 +- DbSigSlot/db_object.cpp | 29 +++++++++++++++++++++++ DbSigSlot/main.cpp | 11 +++++++++ DbSigSlot/object.cpp | 50 ++++++++++++++++++++++++++++++++++++++++ DbSigSlot/object.h | 47 ++++++++++++++++++++++++++++++++++++- README.md | 6 +++-- 6 files changed, 141 insertions(+), 4 deletions(-) create mode 100644 DbSigSlot/db_object.cpp diff --git a/DbSigSlot/CMakeLists.txt b/DbSigSlot/CMakeLists.txt index 6c803cf..e5a6d4b 100644 --- a/DbSigSlot/CMakeLists.txt +++ b/DbSigSlot/CMakeLists.txt @@ -3,4 +3,4 @@ project(DbSigSlot) 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) diff --git a/DbSigSlot/db_object.cpp b/DbSigSlot/db_object.cpp new file mode 100644 index 0000000..2bb844a --- /dev/null +++ b/DbSigSlot/db_object.cpp @@ -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; + } +} diff --git a/DbSigSlot/main.cpp b/DbSigSlot/main.cpp index 95f9add..2713ac5 100644 --- a/DbSigSlot/main.cpp +++ b/DbSigSlot/main.cpp @@ -1,8 +1,19 @@ #include +#include "object.h" 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[]) { + Object *obj1 = new Object(); + Object *obj2 = new Object(); + Object::db_connet(obj1, "sig1()", obj2, "slot1()"); + obj1->testSignal(); return 0; } diff --git a/DbSigSlot/object.cpp b/DbSigSlot/object.cpp index 39fcb2f..6113985 100644 --- a/DbSigSlot/object.cpp +++ b/DbSigSlot/object.cpp @@ -1,6 +1,56 @@ #include "object.h" +#include + +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(sig_idx, c)); // connectionsMap 私有成员 + } +} + +void Object::testSignal() +{ + db_emit sig1(); +} Object::Object() { } + +Object::~Object() +{ + +} + +// 通过 sender 的信号 idx ==> 槽函数 +void MetaObject::active(Object *sender, int idx) +{ + pair 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); + } + +} diff --git a/DbSigSlot/object.h b/DbSigSlot/object.h index 9afcccc..c549683 100644 --- a/DbSigSlot/object.h +++ b/DbSigSlot/object.h @@ -1,11 +1,56 @@ #ifndef OBJECT_H #define OBJECT_H +#include +#include +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 ConnectionMap; +typedef multimap::iterator ConnectionMapIt; 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: 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 \ No newline at end of file +#endif // OBJECT_H diff --git a/README.md b/README.md index 3f563dc..267b47b 100644 --- a/README.md +++ b/README.md @@ -156,10 +156,10 @@ - [QtCreator设置代码美化 astyle 之 Artistic](https://blog.csdn.net/qq_33154343/article/details/101397429) - [Qt Creator 关闭.cpp文件右侧的黄色警告](https://blog.csdn.net/qq_33154343/article/details/102943623) - - [小技巧:Design设计师里,无法拖拽action到toolbar里](https://blog.csdn.net/qq_33154343/article/details/100168170) - [小技巧:设置`QToolBox`的每一页page的使用单独的布局(`QTabWidget`同理)](https://blog.csdn.net/qq_33154343/article/details/100185025) - [小技巧:QtCreator用快捷键秒实现,声明在基类中重写的派生类(纯)虚函数](https://blog.csdn.net/qq_33154343/article/details/104457739) +- [VS2019调试Qt5时QString显示为内存地址而非字符串](https://xmuli.blog.csdn.net/article/details/116244865)
@@ -172,6 +172,7 @@ - [如何给上游 Qt 提交 Bug 反馈和贡献代码 PATCH?](https://xmuli.blog.csdn.net/article/details/107220867) - [Qt 项目用 doxygen 生成 .qch,嵌入文档到 Assistants](https://xmuli.blog.csdn.net/article/details/114580630) - [修改 Doxygen 主题,生成 Qt 风格的文档](https://xmuli.blog.csdn.net/article/details/114591725) +- [QtCreator 中自定义项目例子置于“欢迎-实例”中](https://xmuli.blog.csdn.net/article/details/115049715)
@@ -181,6 +182,7 @@ - [Qt 项目(Cmake)设置国际化支持](https://xmuli.blog.csdn.net/article/details/114439385) - [如何构建 QT5(5.15)](https://xmuli.blog.csdn.net/article/details/114259155) - [在 Mac 编译成功运行 qt5.15 源码:debug 和 release 版本](https://xmuli.blog.csdn.net/article/details/114259186) +- [Qt 信号和槽原理分析](https://xmuli.blog.csdn.net/article/details/115305903)
@@ -252,7 +254,7 @@ ## 作者: -[偕藏 | xmuli ](https://ifmet.cn) +[偕臧 | xmuli ](https://ifmet.cn)