1. 信号与槽机制
Qt的**信号与槽(Signals & Slots)**是观察者模式的典型实现,通过元对象系统(Meta-Object System)实现松耦合通信。
-
核心特点:
- 类型安全:编译时检查参数匹配
- 跨线程支持 :通过
Qt::QueuedConnection
实现线程安全通信 - 动态连接:运行时可添加/移除槽函数
-
代码示例:
cpp// 发射信号(带参数) emit dataFetched("Hello", timestamp); // 连接信号与槽 QObject::connect(button, &QPushButton::clicked, label, &QLabel::clear);
-
Mermaid序列图:
DataFetcher DataProcessor mDataLabel QWidget QApplication paintEvent dataFetched(data="Hello", timestamp=123) 发射信号 process_data(const QString&, int) setText("收到数据:%1 (%2秒)".arg(data).arg(timestamp)) 触发重绘请求 update() 显式触发界面刷新 postEvent(QPaintEvent) deliverEvent(QPaintEvent) 执行绘制逻辑 loop [[Qt事件循环]] DataFetcher DataProcessor mDataLabel QWidget QApplication paintEvent
2. 事件处理机制
Qt通过事件系统 实现观察者模式,事件对象(QEvent
)继承自QObject
,通过重写事件处理函数响应特定事件。
-
关键函数 :
mousePressEvent(QMouseEvent*)
:处理鼠标点击keyPressEvent(QKeyEvent*)
:处理键盘输入paintEvent(QPaintEvent*)
:处理界面重绘
-
代码示例 :
cpp// 重写鼠标事件处理 void MyWidget::mousePressEvent(QMouseEvent *event) { if (event->button() == Qt::LeftButton) { qDebug() << "左键点击坐标:" << event->pos(); // } }
-
Mermaid类图 :
处理 1 * QEvent +QEvent::Type type +QCoreApplication::postEvent() QMouseEvent +Qt::MouseButton button +QPoint pos QWidget +void mousePressEvent(QMouseEvent*) +void paintEvent(QPaintEvent*)
3. 事件过滤器(Event Filter)
通过installEventFilter
实现跨控件事件监听,适用于非父子关系的对象通信。
-
实现步骤 :
- 安装过滤器:
widget->installEventFilter(this)
- 重写
eventFilter(QObject*, QEvent*)
- 安装过滤器:
-
代码示例 :
cpp// 安装事件过滤器 label->installEventFilter(this); // // 拦截Resize事件 bool MyClass::eventFilter(QObject *obj, QEvent *event) { if (event->type() == QEvent::Resize) { qDebug() << "控件尺寸变化:" << obj->size(); // return true; // 停止事件传播 } return QWidget::eventFilter(obj, event); }
-
Mermaid序列图 :
Widget MyClass installEventFilter() 事件触发时调用eventFilter() 处理事件(如Resize) 返回处理结果 Widget MyClass
4. 全局观察者模式
通过单例类实现跨层级消息传递,避免逐层转发。
-
实现代码 :
cpp// 全局观察者类(单例) class GlobalObserver : public QObject { public: static GlobalObserver& instance() { static GlobalObserver observer; return observer; } void notify(const QString& msg) { QMetaObject::invokeMethod(receiver, "update", Qt::QueuedConnection, Q_ARG(QString, msg)); } private: QList<QObject*> m_receivers; }; //
-
使用示例 :
cpp// 注册观察者 GlobalObserver::instance().connect(this, &MyWidget::update); // 发送全局消息 GlobalObserver::instance().notify("数据已更新"); //
-
Mermaid类图 :
观察者 1 * GlobalObserver +QList m_receivers +static GlobalObserver& instance() +void notify(const QString&) MyWidget +void update(const QString&)
5. 自定义观察者模式实现
手动实现接口和聚合关系,适用于复杂业务逻辑。
-
代码示例 :
cpp// 抽象主题接口 class ISubject { public: virtual void registerObserver(IObserver*) = 0; virtual void removeObserver(IObserver*) = 0; virtual void notifyObservers() = 0; }; // 具体主题 class WeatherData : public ISubject { private: QList<IObserver*> m_observers; double m_temperature; public: void registerObserver(IObserver* observer) override { m_observers.append(observer); } void notifyObservers() override { for (auto observer : m_observers) { observer->update(m_temperature); } } }; //
-
Mermaid类图 :
ISubject +registerObserver(IObserver*) +removeObserver(IObserver*) +notifyObservers() IObserver +void update(double) WeatherData +QList m_observers +double m_temperature +registerObserver(IObserver*) +notifyObservers() WeatherDisplay
总结
Qt通过信号与槽 、事件系统 和事件过滤器 原生支持观察者模式,适用于UI交互、多线程通信等场景。对于复杂业务逻辑,可手动实现接口和聚合关系,或通过全局单例类实现跨层级通信。这些机制共同体现了Qt在解耦对象交互、提升扩展性方面的设计优势。