当前位置: 首页 > news >正文

【qt】全局事件总线

#ifndef APPEVENT_HPP
#define APPEVENT_HPP#include <QObject>
#include <QMetaMethod>
#include <QCoreApplication>class AppEvent : public QObject
{Q_OBJECT
public:static AppEvent &instance(){static AppEvent ins;return ins;}void addConnection(QObject *sender, const QMetaMethod &signal,QObject *receiver, const QMetaMethod &slot){if (!sender || !receiver || !signal.isValid() || !slot.isValid())return;const QString key = makeKey(sender, receiver);if (qApp->property(key.toUtf8()).isValid())return; // 已注册QVariantMap m;m["sender"]   = QVariant::fromValue(sender);m["signal"]   = QVariant::fromValue(signal);m["receiver"] = QVariant::fromValue(receiver);m["slot"]     = QVariant::fromValue(slot);qApp->setProperty(key.toUtf8(), m);connect(sender, &QObject::destroyed, this, [this, key](){qApp->setProperty(key.toUtf8(), QVariant());});connect(receiver, &QObject::destroyed, this, [this, key](){qApp->setProperty(key.toUtf8(), QVariant());});}void connectAll(){const QList<QByteArray> keys = qApp->dynamicPropertyNames();for (const QByteArray &k : keys) {if (!k.startsWith("conn_"))continue;QVariantMap m = qApp->property(k).toMap();auto sender   = m["sender"].value<QObject*>();auto signal   = m["signal"].value<QMetaMethod>();auto receiver = m["receiver"].value<QObject*>();auto slot     = m["slot"].value<QMetaMethod>();if (sender && receiver &&QObject::connect(sender, signal, receiver, slot, Qt::UniqueConnection)) {qApp->setProperty(k, QVariant());}}}private:explicit AppEvent(QObject *parent = nullptr) : QObject(parent) {}Q_DISABLE_COPY(AppEvent)static QString makeKey(QObject *s, QObject *r){return QString("conn_%1_%2").arg(reinterpret_cast<quintptr>(s)).arg(reinterpret_cast<quintptr>(r));}
};#endif // APPEVENT_HPP
#ifndef MAINWINDOW_H
#define MAINWINDOW_H#include <QMainWindow>
#include <QObject>
#include "AppEvent.hpp"
#include <QPushButton>class SenderObj : public QObject
{Q_OBJECT
signals:void userLogined(const QString &uid);
public:void testEmit() { emit userLogined("10086"); }
};class ReceiverObj : public QObject
{Q_OBJECT
public slots:void onUserLogined(const QString &uid){qDebug() << "收到用户登录:" << uid;}
};QT_BEGIN_NAMESPACE
namespace Ui {
class MainWindow;
}
QT_END_NAMESPACEclass MainWindow : public QMainWindow
{Q_OBJECTpublic:MainWindow(QWidget *parent = nullptr);~MainWindow();private:Ui::MainWindow *ui;SenderObj   s;ReceiverObj r;QPushButton* btn;public slots:void onBtnPressed();
};
#endif // MAINWINDOW_H
#include "mainwindow.h"
#include "./ui_mainwindow.h"MainWindow::MainWindow(QWidget *parent): QMainWindow(parent), ui(new Ui::MainWindow)
{ui->setupUi(this);btn = new QPushButton(this);btn->setGeometry(100,100,50,50);const QMetaMethod signalMethod = QMetaMethod::fromSignal(&SenderObj::userLogined);const QMetaMethod slotMethod   = r.metaObject()->method(r.metaObject()->indexOfSlot("onUserLogined(QString)"));const QMetaMethod btnPressedSignal = QMetaMethod::fromSignal(&QPushButton::pressed);const QMetaMethod btnSlot = this->metaObject()->method(this->metaObject()->indexOfSlot("onBtnPressed()"));AppEvent::instance().addConnection(&s, signalMethod, &r, slotMethod);AppEvent::instance().addConnection(btn, btnPressedSignal, this, btnSlot);AppEvent::instance().connectAll();
}MainWindow::~MainWindow()
{delete ui;
}void MainWindow::onBtnPressed()
{s.testEmit();
}
http://www.jsqmd.com/news/179/

相关文章:

  • 查询本地IPV6 地址
  • 深入解析:React Device Detect 完全指南:构建响应式跨设备应用的最佳实践
  • ctfshow web89
  • ctfshow web90
  • 解决 Ubuntu 25.04 下 make menuconfig 报 ncurses 错误的问题 - 指南
  • web359
  • 实用指南:Android中handler机制
  • web360
  • 缺失的第一个正数-leetcode
  • hbase的安装应用
  • 如何在后端优雅地生成并传递动态错误提示?
  • ctfshow web357
  • 深入解析:Java全栈开发面试实录:从基础到微服务的实战解析
  • 实用指南:设计模式:建造者模式
  • web358
  • 谁会不爱低温静音 性能还更强的!酷睿Ultra 5 230F vs 锐龙5 9600X生产力、功耗、温度全方位对比
  • 04_Redis凭啥这么牛:核心特性剖析
  • WPF包
  • WPF viewmodel retrieve matched view /window
  • 实用指南:目标检测如何将同时有方形框和旋转框的json/xml标注转为txt格式
  • ctfshow web351
  • ctfshow web353
  • fxztgxj5.dll fxzrs4qj.dll fxztgxa5.dll fxzrs3qj.dll fxzpmc1.dll fxzrs2qj.dll fxzmpxa5.dll - 实践
  • Linux虚拟机常用命令与Hadoop生态组件启动大全
  • 测试新手必学:10个让Bug无处遁形的黑盒测试技巧
  • private void Form1_Load与构造方法前执行顺序
  • 数据分类分级如何高效低成本落地?|高效智能的数据分类分级产品推荐(2025)
  • 文化课暂时计划
  • BGP路由属性与选路-1
  • private void Form1_Load和 private void Form1_Activated 方法区别