QuickEvent

article/2025/10/11 14:49:32

Logo

1 什么是 QuickEvent?

  • ✂️ 仅600行C++代码
  • 🔣 支持多语言,采用 UTF-8 编码
  • ⚡ 使用QuickEvent设计复杂功能可以让开发者,更加专注与自己模块或功能点的开发
  • 💉 利用QT的元对象属性,实现控制类的自动实例化
  • 🔨 高内聚,低耦合,不仅让协同开发变得简单,也让重构变的非常轻松;
  • 🐋 生产级别代码clone即用,提供参考Demo
  • ⚙️️ 跨平台
    platformSupport
    Windos VS-2017 √
    Linux Gcc6 √
    Mac Gcc6 √

2 为何使用 QuickEvent?

1界面与控制逻辑完全分离
2事件管理
3线程管理
4控制类装填

3 如何使用 QuickEvent?

  • QuickEvent使用: 在你的Cmake工程中添加QuickEvent
  • QuickEvent开发: 您可以获得源码,并在任何平台(Windows/Linux/Mac)上开发它

          QuickEvent开发

  1. Fork 本仓库
  2. 新建 Feat_xxx 分支
  3. 提交代码
  4. 新建 Pull Request

           QuickEvent使用

3.1 发布和订阅

3.1.1.关联QuickEvent

  引入QUICK_EVENT宏让你的自己定义的类具有发布和订阅事件的能力;
  QuickWork、QuickScript默认已经引入QUICK_EVENT。

// 使用QUICK_EVENT宏
class Dialog : public QDialog {Q_OBJECTQUICK_EVENT(QDialog)public:explicit Dialog(QWidget *parent = nullptr);...
};// 继承自QuickWork
class UserWork : public QuickWork {Q_OBJECTpublic:Q_INVOKABLE explicit UserWork(QObject *parent = nullptr);...
};
  • 注:QObject及其子类才能通过QUICK_EVENT宏引入发布订阅;

3.1.2.订阅消息

  QuickApplication提供了subscibeEvent方法用来订阅一个消息。
  QUICK_SUBSCIBE宏可以实现便捷订阅。

// 订阅show_time消息
Dialog::Dialog(QWidget *parent) :QDialog(parent),ui(new Ui::Dialog) {ui->setupUi(this);QuickApplication::subscibeEvent(this, "show_time");...
}// QUICK_SUBSCIBE便捷订阅事件
SessionManager::SessionManager(QuickWork *parent) :QuickWork(parent) {QUICK_SUBSCIBE("Manager_LoginType")QUICK_SUBSCIBE("Widget_SessionType")this->Initial();
}

  QUICK_SUBSCIBE定义:

#define QUICK_SUBSCIBE_OBJ(obj,name)\QuickApplication::subscibeEvent(obj, name);
#define QUICK_SUBSCIBE(name)\QuickApplication::subscibeEvent(this, name);
#define QUICK_SUBSCIBE_H(name,lev)\QuickApplication::subscibeEvent(this, name,lev);
#define QUICK_SUBSCIBE_L(name,lev)\QuickApplication::subscibeEvent(this, name,100+lev);

3.1.3.发布消息

  QuickApplication提供了publishEvent方法用来发布一个消息。
  QUICK_PUBLISH1宏可以实现便捷发布事件。

// 发布show_time消息
TestWork::TestWork(QObject *parent) : QuickWork(parent) {QTimer::singleShot(2000, this, []() {auto time = QDateTime::currentDateTime();QuickApplication::publishEvent("show_time", Qt::AutoConnection, time);});
}// QUICK_PUBLISH便捷发布消息
void RightControlManager::Slot_WidgetRightControlType(const qint32 &type) {switch (type) {case RightControlWidget::Remodel: {QUICK_PUBLISH1("Manager_RightControlType", qint32(RightControlWidget::Remodel))break;}default:break;}
}

  publishEvent定义:

template<class ...Args>
static void publishEvent(QByteArray eventName, Qt::ConnectionType type, Args &&... args) {...
}

  QUICK_PUBLISH定义:

  • 自 动 模式发布  QUICK_PUBLISHX,X表示发布参数数量
  • 同步触发模式发布  QUICK_Direct_PUBLISHX,X表示发布参数数量
  • 异步触发模式发布  QUICK_Queued_PUBLISHX,X表示发布参数数量
  • 异步等待模式发布  QUICK_BlockingQueued_PUBLISHX,X表示发布参数数量
#define QUICK_PUBLISH1(name,arg1)\QuickApplication::publishEvent(name,Qt::AutoConnection, arg1);
#define QUICK_PUBLISH2(name,arg1,arg2)\QuickApplication::publishEvent(name,Qt::AutoConnection, arg1,arg2);
#define QUICK_PUBLISH3(name,arg1,arg2,arg3)\QuickApplication::publishEvent(name,Qt::AutoConnection, arg1,arg2,arg3);
#define QUICK_PUBLISH4(name,arg1,arg2,arg3,arg4)\QuickApplication::publishEvent(name,Qt::AutoConnection, arg1,arg2,arg3,arg4);#define QUICK_Direct_PUBLISH1(name,arg1)\QuickApplication::publishEvent(name,Qt::DirectConnection, arg1);
#define QUICK_Direct_PUBLISH2(name,arg1,arg2)\QuickApplication::publishEvent(name,Qt::DirectConnection, arg1,arg2);
#define QUICK_Direct_PUBLISH3(name,arg1,arg2,arg3)\QuickApplication::publishEvent(name,Qt::DirectConnection, arg1,arg2,arg3);#define QUICK_Queued_PUBLISH1(name,arg1)\QuickApplication::publishEvent(name,Qt::QueuedConnection, arg1);
#define QUICK_Queued_PUBLISH2(name,arg1,arg2)\QuickApplication::publishEvent(name,Qt::QueuedConnection, arg1,arg2);
#define QUICK_Queued_PUBLISH3(name,arg1,arg2,arg3)\QuickApplication::publishEvent(name,Qt::QueuedConnection, arg1,arg2,arg3);#define QUICK_BlockingQueued_PUBLISH1(name,arg1)\QuickApplication::publishEvent(name,Qt::BlockingQueuedConnection, arg1);
#define QUICK_BlockingQueued_PUBLISH2(name,arg1,arg2)\QuickApplication::publishEvent(name,Qt::BlockingQueuedConnection, arg1,arg2);
#define QUICK_BlockingQueued_PUBLISH3(name,arg1,arg2,arg3)\QuickApplication::publishEvent(name,Qt::BlockingQueuedConnection, arg1,arg2,arg3);
  • 注:使用Qt::AutoConnection,发布消息时,跨线程处于采用异步触发。

3.1.4.接受并处理消息

  引入发布和订阅功能的类通过实现event_ + 消息名称的槽函数即可接受并处理publishEvent推送消息

private slots:void event_show_time(const QDateTime &time);
...
void Dialog::event_show_time(const QDateTime &time) {box->setText(time.toString());box->show();
}
  • 注:需要函数参数列表匹配一致

3.1.5.取消订阅

  QuickApplication提供了UnsubscribeEvent方法用来取消订阅消息。
  QUICK_DESTRUCT宏可以实现便捷取消订阅。

  UnsubscribeEvent定义:

bool QuickApplication::UnsubscribeEvent(QObject *listener, QByteArray eventName) {QWriteLocker loker(&s_lock);bool result = false;if(s_quick_event_pool.contains(eventName)) {QMap<qint32, QObject *> tmplist = s_quick_event_pool[eventName];tmplist.remove(tmplist.key(listener));s_quick_event_pool.insert(eventName, tmplist);result = true;}if(s_quick_event_pool_high.contains(eventName)) {QMap<qint32, QObject *> tmplist = s_quick_event_pool[eventName];tmplist.remove(tmplist.key(listener));s_quick_event_pool.insert(eventName, tmplist);result = true;}if(s_quick_event_pool_low.contains(eventName)) {QMap<qint32, QObject *> tmplist = s_quick_event_pool[eventName];tmplist.remove(tmplist.key(listener));s_quick_event_pool.insert(eventName, tmplist);result = true;}return result;
}bool QuickApplication::UnsubscribeEvent(QObject *listener) {QWriteLocker loker(&s_lock);foreach (auto var, s_quick_event_pool.keys()) {s_quick_event_pool[var].remove(s_quick_event_pool[var].key(listener));}foreach (auto var, s_quick_event_pool_low.keys()) {s_quick_event_pool[var].remove(s_quick_event_pool[var].key(listener));}foreach (auto var, s_quick_event_pool_high.keys()) {s_quick_event_pool[var].remove(s_quick_event_pool[var].key(listener));}return true;
}

  QUICK_DESTRUCT定义:

#define QUICK_DESTRUCT \QuickApplication::UnsubscribeEvent(this);\

3.1.6.订阅优先级

  默认情况下跟Qt的信号槽一样,根据订阅顺序依次接受并处理消息。QuickEvent把订阅者分为三类,高级别、默认、低级别。当发布消息后,所有订阅者按照高级订阅、默认订阅、低级订阅的顺序依次执行。其中高级订阅和低级订阅分别有自己的顺序,默认订阅则无序。

  static QMap < QByteArray, QMap<qint32, QObject *> > s_quick_event_pool_high;static QMap < QByteArray, QMap<qint32, QObject *> > s_quick_event_pool;static QMap < QByteArray, QMap<qint32, QObject *> > s_quick_event_pool_low;

3.1.7.发布订阅类型

  QuickEvent发布订阅支持四种模式。
  请注意,使用QuickEvent时往往不清楚对方详细代码,使用阻塞发布请务必小心,防止死锁!

  ConnectionType::AutoConnection,// 自动模式发布,// 订阅者者和发布者在同一个线程使用同步调用。// 订阅者和发布者不在一个线程采用异步调用。// 调用时按照顺序执行 QuickApplication::methodIndex调用ConnectionType::DirectConnection,  同步触发模式发布// 把本线程所有订阅者打包到一个列队依次顺序执行ConnectionType::QueuedConnection,  异步触发模式发布// 把每个线程单独打包成列队,每个线程内依次执行   QApplication::postEventConnectionType::BlockingQueuedConnection,  异步等待模式发布// 把所有线程所有订阅者按照订阅顺序打包,依次调用// QuickApplication::methodIndex调用

3.2 控制类装填

  Quick Event代码模型提供两个控制类: QuickWork、QuickScript

3.2.1 QuickScript及其子类:

  继承自QThread的脚本基类,使用方式

  初始化:

  1. 实例化
  2. 指定渲染窗口ui(如果有)
  3. 绑定QThread::finished()

  执行执行:

  1. 开启渲染窗口交互
  2. 交互完成传入脚本计算数据、参数
  3. 执行计算脚本
  4. 开启渲染窗口交互
  5. 关闭渲染窗口交互

  结束:

  1. deleteLater();

  注意:

  1. 整个类仅Execute()位于新线程内,其余(渲染窗口交互)所有均位于父线程。
  2. 提供 Wait、Wake接口,可以在计算脚本中穿插交互
  3. 提供SignalProgressIn信号用来打印脚本计算进度

3.2.2 QuickWork及其子类:

  允许被反射,通过QUICK_AUT宏和QuickController,可以实现控制类的自动实例化。
  QuickController类用来实现反射,其内部统一自动实例化QuickWork及其子类。QuickWork的线程归属可以通过 move_type来决定被反射后移动大到线程的位置。

MainThread = 0, //反射在主线程中且不移动,start函数不能为死循环否者QT事件循环也将被卡死;
WorkThread,     //反射在工作线程中,区别与主线程;
NewThread       //反射在新的线程中,会被每个反射出对象创建一个新的线程;

  QUICK_AUTO宏作用

  1. 向QT元对象系统注册自己类型
  2. 在mian方法之前将自己类名注册到需要反射类列表中,QuickController对象创建后会反射出所有已注册的类,并做线程归属处理

  QUICK_AUTO定义:

#define QUICK_AUTO(ClassName)\Q_DECLARE_METATYPE(ClassName *) \static int ClassId##ClassName = qRegisterMetaType<ClassName *>();\static void *ThisPtr##ClassName = QuickController::NewInstance(#ClassName);#define QUICK_AUTO_H(ClassName,value)\Q_DECLARE_METATYPE(ClassName *) \static int ClassId##ClassName = qRegisterMetaType<ClassName *>();\static void *ThisPtr##ClassName = QuickController::NewInstance(\#ClassName,QuickController::High,value);#define QUICK_AUTO_L(ClassName,value)\Q_DECLARE_METATYPE(ClassName *) \static int ClassId##ClassName = qRegisterMetaType<ClassName *>();\static void *ThisPtr##ClassName = QuickController::NewInstance(\#ClassName,QuickController::Low,value);

  QuickController反射QuickWork及其子类顺序类似订阅顺序,分为三个级别。高优先级、默认、低优先级。先反射高优先级类、默认优先级类、低优先级类。其中默认优先级里的类无序,高优先级、低优先级里类有序。

  原理:C/C++无法在main之前执行复杂的操作,通过在.h文件中定义static变量且通过函数方式赋值,可以main之前执行一段代码,利用static在类外修饰变量表示该变量仅对于文件内部可见的原理,不会产生编译错误;[当然对C++11支持良好编译器可以使用constexpr]但是这个操作可能被执行多次,所以反射类列表使用了Set容器防止重复插入;

  • 注:1. 继承自QuickWork后可以覆盖QuickWork::start函数,start函数一定会在被移动到的线程中调用;
  • 注:2. 高优先级、低优先级如果插入重复顺序会打印重复信息,让后只反射其中一个;
----------------- QuickController OrderLow cover:----------------- 
cover key: 25 
cover name: "TestWork" "UserWork" 
----------------------------------

3.3 QuickEvent 初始化

  只使用QuickEvent的发布订阅功能无需初始化。QuickEvent的控制类反射与生存周期管理QuickController需要在main函数中初始化。
   QUICK_INSTALL() 宏和 QUICK_INSTALL_DETAILED() 宏均可实现初始化,QUICK_INSTALL_DETAILED() 增加了打印 QuickEvent 更详细的相关信息,比如版本信息、详细发布订阅列队等,方便调试使用。

#include "dialog.h"
#include <QuickEvent>
#include <QFile>
int main(int argc, char **argv) {QApplication a(argc, argv);QUICK_INSTALL()// QUICK_INSTALL  QUICK_INSTALL_DETAILEDQUICK_SETSTYLE("../../Examples/resource/Style/gray_style.qss")Dialog dialog;dialog.show();return a.exec();
}

3.4 QuickEvent 所有宏介绍

QuickEvent说明
QUICK_AUTO(ClassName)向QT元对象系统注册自己类型、实例化本身(默认优先级)
QUICK_AUTO_H(ClassName,value)向QT元对象系统注册自己类型、实例化本身(高优先级)
QUICK_AUTO_L(ClassName,value)向QT元对象系统注册自己类型、实例化本身(低优先级)
QUICK_EVENT(PARENTANME)使类本身支持发布订阅功能
--
QUICK_DESTRUCT取消自身的所有订阅
--
QUICK_SUBSCIBE_OBJ(obj,name)便捷订阅,订阅者、订阅名称(订阅者可以是自己内部变量)
QUICK_SUBSCIBE(name)向自身便捷订阅
QUICK_SUBSCIBE_H(name,lev)向自身便捷高级订阅,lev表示高级订阅中的排序,重复则顶掉之前
QUICK_SUBSCIBE_L(name,lev)向自身便捷低级订阅,lev表示低级订阅中的排序,重复则顶掉之前
--
QUICK_PUBLISH1(name,arg1)默认模式发布,1个参数
QUICK_PUBLISH2(name,arg1,arg2)默认模式发布,2个参数
QUICK_PUBLISH3(name,arg1,arg2,arg3)默认模式发布,3个参数
QUICK_PUBLISH4(name,arg1,arg2,arg3,arg4)默认模式发布,4个参数
QUICK_Direct_PUBLISH1(name,arg1)同步模式发布,1个参数
QUICK_Direct_PUBLISH2(name,arg1,arg2)同步模式发布,2个参数
QUICK_Direct_PUBLISH3(name,arg1,arg2,arg3)同步模式发布,3个参数
QUICK_Queued_PUBLISH1(name,arg1)异步模式发布,1个参数
QUICK_Queued_PUBLISH2(name,arg1,arg2)异步模式发布,2个参数
QUICK_Queued_PUBLISH3(name,arg1,arg2,arg3)异步模式发布,3个参数
QUICK_BlockingQueued_PUBLISH1(name,arg1)异步等待模式发布,1个参数
QUICK_BlockingQueued_PUBLISH2(name,arg1,arg2)异步等待模式发布,2个参数
QUICK_BlockingQueued_PUBLISH3(name,arg1,arg2,arg3)异步等待模式发布,3个参数
--
QUICK_GETSET(name,type)变量快速读写接口
QUICK_INITIAL_VAR(name,type)变量快速定义、读写接口
QUICK_GETSET_Object(name,type)指针快速读写接口
--
QUICK_INSTALL()QuickController初始化
QUICK_INSTALL_DETAILED()QuickController初始化,打印详细信息
QUICK_SETSTYLE(name)样式表初始化

4 版本更新说明

更新2.0.0版本

  1. 通过引入变参模板使得事件响应函数(event_ + 消息名称)的定义更加自由;
  2. 发布订阅支持了:
      同步触发[DirectConnection];
      异步触发[QueuedConnection];
      异步触发等待[BlockingQueuedConnection];
存在问题:
  • 1.事件发布后如何确定调用触发函数匹配仍然不够完美;

  问题在于QT元对象系统对于方法参数类型的摘要(QMetaMethod::parameterTypes)和C++的typeid()差距过大。目前只匹配外部类型,对于模板无法处理,所以不建议重载参数个数相同的事件响应函数。比如:

void event_show_time(const QDateTime &time, QList<int> list);
void event_show_time(const QDateTime &time, QList<QString> list);
注意
  1. 跨线程的事件发布传递参数需要使用QT已知的类型
  2. 同使用QT的QMetaObject::QMetaCallEvent一样QuickEvent在处理跨线程异步触发时也会在堆中创建变量的副本;
  3. 消息订阅者可能是多个,使用QSharedPointer::QVariant共享这块内存;所以传入参数会被转换成QVariant类型。
  4. 未知类型在编译时就会报错;
  5. 对于同步触发和异步触发等待,则支持任意类型参数;

更新2.0.2版本

  1. QuickEvent使用cmake来组织工程了,添加编译动态库版本,参考CMakeLists.txt;
#true编译生成动态库; false编译生成静态库;
set(quickevent_BUILD_SHARED_LIBS false)
#ON编译示例 OFF不编译示例
set(quickevent_BUILD_EXAMPLES ON)
  1. 解决继承动自导出类后反射崩溃问题,以下摘自QT源码:qmetatype.h;
 static int qt_metatype_id(){static QBasicAtomicInt metatype_id = Q_BASIC_ATOMIC_INITIALIZER(0);if (const int id = metatype_id.loadAcquire())return id;//继承自dll导出类的对象T模板类型无法识别,需要Q_DECLARE_METATYPE前置声明const char * const cName = T::staticMetaObject.className();...}

更新3.0.0版本

  1. 文件结构重新整理,便于快速整合到现有工程;
  2. 增加若干宏,使调用QuickEvnet发布订阅时代码更加整洁;
  3. 取消QuickApplication构造析构函数,剔除对原有Qt框架的侵入性
  4. 增加QuickEventConfig.h.in文件控制版本
  5. 增加QuickScript
  6. 优化QuickController初始化
  7. QuickWork内部变量增加setter/getter
  8. 整理了下cmkae的example调用逻辑,方便后期增加案例

更新3.0.1版本

  1. 增加若干案例
  2. 修复反射NewThread实例时,析构失败错误
  3. 优化详细打印
  4. 增加QuickController 增加排序注册

3.X.X 版本计划

  1. 增加多个案例,展示QuickEvnet所有接口使用方式
  2. 修复3.0.0更新后引入的bug

5 Examples介绍

Example1:完整功能展示

Example2:自动实例化 QuickApplication、QuickWork 排序反射展示

----------------- QuickController Initialization:----------------- 
Lib Name: "QuickEvent" 
Lib VER: "3.0.1" 
Controlle QuickWorks: ("High0", "High1", "High2", "Disorder2", "Disorder1", "Disorder0", "Low0", "Low1", "Low2") 
----------------------------------"High0  Initialization complete"
"High1  Initialization complete"
"High2  Initialization complete"
"Disorder2  Initialization complete"
"Disorder1  Initialization complete"
"Disorder0  Initialization complete"
"Low0  Initialization complete"
"Low1  Initialization complete"
"Low2  Initialization complete"
"High0  End of deconstruction"
"High1  End of deconstruction"
"High2  End of deconstruction"
"Disorder2  End of deconstruction"
"Disorder1  End of deconstruction"
"Disorder0  End of deconstruction"
"Low0  End of deconstruction"
"Low1  End of deconstruction"
"Low2  End of deconstruction"
  • 注:1. Disorder反射乱序的,设计到有先后顺序需要注意

Example3:自动实例化 QuickApplication、QuickWork 线程归属展示

----------------- QuickController Initialization:----------------- 
Lib Name: "QuickEvent" 
Lib VER: "3.0.1" 
Controlle QuickWorks: ("Disorder3", "Disorder2", "Disorder0", "Disorder1") 
----------------------------------Disorder3 Initialization QThread(0x1b9428d5fa0, name = "Main Thread")
Disorder2 Initialization QThread(0x1b9428d5fa0, name = "Main Thread")
Disorder0 Initialization QThread(0x1b9428d5fa0, name = "Main Thread")
Disorder1 Initialization QThread(0x1b9428d5fa0, name = "Main Thread")
Disorder0 Run QThread(0x1b9428d5fa0, name = "Main Thread")
Disorder2 Run QThread(0x1b9428f94c0)
Disorder3 Run msleep Begin QThread(0x1b9428f9400, name = "Work Thread")
Disorder3 Run msleep End QThread(0x1b9428f9400, name = "Work Thread")
Disorder1 Run msleep Begin QThread(0x1b9428f9400, name = "Work Thread")
Disorder1 Run msleep End QThread(0x1b9428f9400, name = "Work Thread")
-------------quit-------------
"Disorder2  End of deconstruction"
"Disorder3  End of deconstruction"
"Disorder1  End of deconstruction"
"Disorder0  End of deconstruction"
  • 注:1. WorkThread下线程类似MainThread,阻塞依次执行

Example4:发布订阅 跨线程发布订阅

WorkThread的start耗时操作会阻塞所有WorkThread中订阅事件

----------------- QuickController Initialization:----------------- 
Lib Name: "QuickEvent" 
Lib VER: "3.0.1" 
Controlle QuickWorks: ("MainThreadSubscibe", "MainThreadPublish", "NewThreadPublish", "WorkThreadPublish", "NewThreadSubscibe", "WorkThreadSubscibe") 
-----------------------------------------------Main Thread Publish------------------------------ publishEvent:----------------- 
Event name:  "Example4" 
Event ConnectionType: Qt::AutoConnection 
Event Args: Qt::AutoConnection 
Event Thread: QThread(0x20815dc6640, name = "Main Thread") 
----------------------------------MainThreadSubscibe QThread(0x20815dc6640, name = "Main Thread")
NewThreadSubscibe QThread(0x20815df18b0)-------------Work Thread Publish------------------------------ publishEvent:----------------- 
Event name:  "Example4" 
Event ConnectionType: Qt::AutoConnection 
Event Args: Qt::AutoConnection 
Event Thread: QThread(0x20815de8820, name = "Work Thread") 
----------------------------------WorkThreadSubscibe QThread(0x20815de8820, name = "Work Thread")
MainThreadSubscibe QThread(0x20815dc6640, name = "Main Thread")
NewThreadSubscibe QThread(0x20815df18b0)
WorkThreadSubscibe QThread(0x20815de8820, name = "Work Thread")-------------New Thread Publish------------------------------ publishEvent:----------------- 
Event name:  "Example4" 
Event ConnectionType: Qt::AutoConnection 
Event Args: Qt::AutoConnection 
Event Thread: QThread(0x20815de86c0) 
----------------------------------MainThreadSubscibe QThread(0x20815dc6640, name = "Main Thread")
NewThreadSubscibe QThread(0x20815df18b0)
WorkThreadSubscibe QThread(0x20815de8820, name = "Work Thread")
-------------Quit-------------
  • 注:1. WorkThread的start耗时操作会阻塞所有WorkThread中订阅事件

Example5:发布订阅 多种发布展示(同步、异步、异步等待、自动)

----------------- QuickController Initialization:----------------- 
Lib Name: "QuickEvent" 
Lib VER: "3.0.1" 
Controlle QuickWorks: ("NewThreadSubscibe1", "NewThreadSubscibe2") 
--------------------------------------------------- subscibeEvent:----------------- 
listener: NewThreadSubscibe1(0x23c34998610) 
Event name: "Example5" 
subscibe level Disorder 
Event Thread "Main Thread" 
--------------------------------------------------- subscibeEvent:----------------- 
listener: NewThreadSubscibe2(0x23c34998950) 
Event name: "Example5" 
subscibe level Disorder 
Event Thread "Main Thread" 
-----------------------------------------------Direct PUBLISH------------------------------ publishEvent:----------------- 
Event name:  "Example5" 
Event ConnectionType: Qt::DirectConnection 
Event Args: Qt::DirectConnection 
Event Thread: QThread(0x23c34976690, name = "Main Thread") 
----------------------------------New1 Subscibe bugin QThread(0x23c34998570)
New2 Subscibe bugin QThread(0x23c349988d0)
New2 Subscibe end QThread(0x23c349988d0)
New1 Subscibe end QThread(0x23c34998570)-------------Queued PUBLISH------------------------------ publishEvent:----------------- 
Event name:  "Example5" 
Event ConnectionType: Qt::QueuedConnection 
Event Args: Qt::QueuedConnection 
Event Thread: QThread(0x23c34976690, name = "Main Thread") 
----------------------------------New1 Subscibe bugin QThread(0x23c34998570)
New2 Subscibe bugin QThread(0x23c349988d0)
New2 Subscibe end QThread(0x23c349988d0)
New1 Subscibe end QThread(0x23c34998570)-------------Blocking Queued PUBLISH------------------------------ publishEvent:----------------- 
Event name:  "Example5" 
Event ConnectionType: Qt::BlockingQueuedConnection 
Event Args: Qt::BlockingQueuedConnection 
Event Thread: QThread(0x23c34976690, name = "Main Thread") 
----------------------------------New1 Subscibe bugin QThread(0x23c34998570)
New1 Subscibe end QThread(0x23c34998570)
New2 Subscibe bugin QThread(0x23c349988d0)
New2 Subscibe end QThread(0x23c349988d0)-------------Auto PUBLISH1------------------------------ publishEvent:----------------- 
Event name:  "Example5" 
Event ConnectionType: Qt::AutoConnection 
Event Args: Qt::AutoConnection 
Event Thread: QThread(0x23c34976690, name = "Main Thread") 
----------------------------------New1 Subscibe bugin QThread(0x23c34998570)
New2 Subscibe bugin QThread(0x23c349988d0)
New2 Subscibe end QThread(0x23c349988d0)
New1 Subscibe end QThread(0x23c34998570)
-------------Quit-------------
"NewThreadSubscibe1  End of deconstruction"
"NewThreadSubscibe2  End of deconstruction"
  • 注:1. 小心死锁,尤其跨线程阻塞同步、带QDialog等有返回值的窗口请勿使用阻塞发布

。。。。持续增加中

6 QuickEvnet代码模型使用心得




7 关于作者

Bruce
Gitee
https://gitee.com/fmldd
个人博客
https://me.csdn.net/dadabruce

Beyond欣
Gitee
https://gitee.com/yaoxin001
个人博客
http://118.25.63.144









本文仓库 https://gitee.com/fmldd/Quick-Event


http://chatgpt.dhexx.cn/article/DqZNCCm2.shtml

相关文章

Quick Power

6-3 Quick Power &#xff08;10 分&#xff09; The function Power calculates the exponential function N​k​​. But since the exponential function grows rapidly, you are supposed to return (N​k​​)%10007instead. Format of function: int Power(int N, int…

QuickHit项目

玩家类&#xff1a; package QuickHit;import java.util.Scanner;/*** * author 呵呵* 玩家类**/ public class Player {//当前级别号private int levelNo;//当前级别积分private int currScore;//当前级别开始时间private long startTime0; //当前级别以用时间private int ela…

quickAction

有一段时间没有上来折腾这个专题了&#xff0c;一来项目的确紧张&#xff0c;二来自己一惯是很懒的。今天想与大家分享的是一个QuickAction的东西&#xff0c;模样其实就是通讯录中点击头像后弹出的那个提供可操作按钮的窗口。 这个效果其实我们也用过&#xff0c;就是QuickCon…

快速检查(QuickCheck)(译)

source: http://www.jianshu.com/p/bb93972bac53 快速检查&#xff08;QuickCheck&#xff09;&#xff08;译&#xff09; 作者 低智商游戏 2016.02.01 00:26* 字数 4778 阅读 239 评论 0 喜欢 0 本文译自 objc.io出品的书籍《Functional Programming in swift》第六章&#…

quickbi使用

在maxcomputer中建表时应该注意四种建表方式不能使用临时查询的方式建立表结构&#xff0c;这种无法提交到生产环境&#xff0c;虽然在数据地图中可以查询到&#xff0c;但没提交生产环境中 暂时不知道这种情况&#xff1a;通过数据地图可以看到测试表通过临时查询简报方式也在…

阴阳师模型提取

0.声明 本文中的开发工具、第三方资源均用于学习用途&#xff0c;而非商业用途。本文中所有资源截止发稿时已全部删除 1.前言 最近一直在玩阴阳师。玩的时候我们不难观察到&#xff0c;现代游戏的制作中&#xff0c;画面、游戏体验都大大改善&#xff0c;除此之外&#xff0…

QUICKBMS 中文指南

我正打算做一个使用Quickbmsqu去解那些没有解包器的文档的教程。6 ?- s/ g/ B8 }, a$ ` 起步会很简单,然后越来越难,直到你学会并且编写你自己的脚本。 我们需要如下的四个工具: 1、16进制编辑器,比如HxD。(我用WINHEX) 2、Quick BMS http://aluigi.org/papers/quickbm…

quick bms的使用

下载工具quick bms&#xff0c;官网&#xff1a;http://aluigi.altervista.org/quickbms.htm 新建脚本 Script File -> New 选择你要操作的文件 Archive File -> Open Archive 选择输出目录 Folders -> Select Out Folder 编写脚本&#xff0c;点Quick Save保存脚…

乘方及方根运算电路

乘方及方根运算电路 图5.4-36是乘方运算电路。由于相乘器相移的影响&#xff0c;高次方运算会带来很大误差&#xff0c;通常串接的相乘器数量不超过2~3个。 图5.4-37是开方运算电路。要使此开方电路能稳定地工作&#xff0c;输入电压U1必须为负值。如果U1为正&#xff0c;将形…

比例运算电路(multisim实现)

目录 1.同相比例运算电路 ​ 输入与输出关系&#xff1a;​ 2.反相比例运算电路 输入与输出关系&#xff1a;​ 1.同相比例运算电路 仿真波形&#xff1a; 输入与输出关系&#xff1a; 2.反相比例运算电路 R2扫描波形 输入与输出关系&#xff1a;

模电总结二:基本运算电路

一、比例运算放大电路 二、加法运算放大电路 三、减法运算电路 四、积分运算电路 五、微分运算电路

大学模电实验合集丨实验六 比例求和运算电路

目录 一、实验目的 二、实验仪器 三、实验要求 五、根据实验报告回答下列问题 一、实验目的 1.掌握用集成运算放大电路组成比例、求和电路的特点及性能。 2.学会上述电路的测试和分析方法。 二、实验仪器 1.示波器 2.信号发生器 3.数字万用表 三、实验要求 在 MultiS…

【模拟电子技术Analog Electronics Technology 24】—— 信号的运算与处理(1):基本的运算电路分析

写在前面&#xff1a;在本篇博文中&#xff0c;我将分析几种常见的基本运算电路&#xff1a;比例运算电路&#xff0c;加减运算电路&#xff0c;微分和积分运算电路&#xff0c;指数和对数运算电路输入与输出的关系。但是&#xff0c;掌握单一的运算电路并不是我们的最终目的&a…

计算机系统基础(三)——运算电路基础

运算电路基础 数字逻辑电路基础运算电路基础数字逻辑电路基础 从C语言表达式到逻辑电路C语言支持的基本数据类型从C表达式到运算类指令从运算类指令到运算电路 C语言中各类运算算术运算按位运算逻辑运算移位运算截断和扩展运算 整数加减运算补码加减运算器无符号整数加法溢出判…

运算放大电路(比例运算电路)

0.反向比例运算电路 这是典型的并联反馈负反馈电路&#xff0c;输入电压U1通过电阻R作用于反向输入端&#xff0c;故输出电压与输入电压反向&#xff0c;同相输入端通过补偿电阻R接地&#xff0c;其值为U10时反相输入端的等效电阻&#xff0c;即各支路电阻的并联&#xff0c;因…

正弦运算电路

在很久之前&#xff0c;我在寻找一个能够进行正弦信号的电路。这个电路的意思不是说DDS正弦信号发生器。而是说&#xff0c;当输入一个信号x时&#xff0c;输出信号ysin⁡(x)&#xff0c;也就是说&#xff0c;输入信号xπ/2 V时&#xff0c;输出y1V&#xff0c;输入信号xπV时&…

模电笔记 基本运算电路

理想运放 “虚断” 理想运放的输入电阻为无穷大&#xff0c;流入两个输入端的电流近似为0 “虚短” 条件&#xff1a;理想运放工作于线性区&#xff08;存在负反馈&#xff09; 虚短&#xff1a;两个输入端的电位近似相等&#xff0c;净输入电压近似为0 比例运算电路 反…

实验二十一、积分运算电路的输出波形分析

一、题目 利用 Multisim 分析图1所示两个积分运算电路的输出波形&#xff0c;输入电压为 200 Hz、幅值为 1 V 的方波信号。 图 1 图1\,\, 图1 二、仿真电路 在 Multism 中搭建图1所示的两个电路&#xff0c;如图2所示。为了防止电路中的直流增益过大&#xff0c;故在电容上…

【反向和同向比例运算电路】

反向和同向比例运算电路 1.1 反相比例电路 1. 基本电路 电压并联负反馈输入端虚短、虚断   特点&#xff1a;   反相端为虚地&#xff0c;所以共模输入可视为0&#xff0c;对运放共模抑制比要求低   输出电阻小&#xff0c;带负载能力强   要求放大倍数较大时&#x…

减法器运算电路公式推导

前言 本人是菜鸟&#xff0c;有错误欢迎斧正&#xff0c;近期在看仪表放大器&#xff0c;其第二级放大电路就是一个减法器&#xff0c;大学教的我也忘的差不多了&#xff0c;于是开始网上冲浪&#xff0c;可是网上都是根据具体电路分析&#xff0c;或者分析的跳跃度很大&#…