IT评测·应用市场-qidao123.com
标题:
观察者模式详解:用 Qt 信号与槽机制深入明白
[打印本页]
作者:
一给
时间:
2025-3-22 07:30
标题:
观察者模式详解:用 Qt 信号与槽机制深入明白
弁言
你是否曾碰到如许的需求:一个对象的状态发生变革后,盼望通知其他对象进行相应的更新?好比:
新闻订阅系统
:当新闻发布后,所有订阅者都会收到通知。
股票行情推送
:股价变革时,所有关注该股票的投资者都会收到更新信息。
Qt 界面开发
:按钮被点击时,窗口应该发生某些变革。
这些场景都适用于
观察者模式(Observer Pattern)
。
在本篇文章中,我们不仅讲清楚观察者模式的结构,还会用
Qt 的信号与槽机制
来深入剖析,让你真正明白这一模式的奥秘!
1. 什么是观察者模式?
观察者模式是一种
一对多
的计划模式,答应多个对象(观察者)监听某个对象(被观察者)的状态变革,并在变革时收到通知。
简单来说:
被观察者(Subject)
:负责维护一个观察者列表,并在状态发生变革时通知所有观察者。
观察者(Observer)
:吸收被观察者的通知并做出相应反应。
现实例子:
场景
被观察者(Subject)
观察者(Observer)
微信公众号订阅公众号订阅的用户股票市场股票关注股票的投资者UI 界面按钮点击按钮(QPushButton)监听点击的槽函数
2. 观察者模式的结构
观察者模式一样平常包括以下脚色:
Subject(被观察者)
:
维护一个
观察者列表
(即谁在关注它)。
当自身状态发生变革时,通知所有观察者。
Observer(观察者)
:
订阅 Subject,并实现 update() 方法,吸收状态变革通知。
通知机制
:
Subject 需要提供 attach() 和 notify() 方法,管理观察者并进行通知。
观察者模式 UML 结构图
+-------------+ +----------------+
| Observer |<------| Subject |
+-------------+ +----------------+
| +update() | | +attach() |
| | | +detach() |
| | | +notify() |
+-------------+ +----------------+
复制代码
3. 传统 C++ 实现观察者模式
在 C++ 中,我们可以用 vector 存储观察者列表,并手动通知它们:
传统 C++ 实现
#include <iostream>
#include <vector>
// 观察者接口
class Observer {
public:
virtual void update(int value) = 0;
};
// 被观察者(Subject)
class Subject {
private:
std::vector<Observer*> observers;
int state;
public:
void attach(Observer* observer) { observers.push_back(observer); }
void notify() {
for (Observer* obs : observers) {
obs->update(state);
}
}
void setState(int value) {
state = value;
notify();
}
};
// 具体观察者
class ConcreteObserver : public Observer {
public:
void update(int value) override {
std::cout << "Observer received update: " << value << std::endl;
}
};
int main() {
Subject subject;
ConcreteObserver observer1, observer2;
subject.attach(&observer1);
subject.attach(&observer2);
subject.setState(42); // 触发通知
}
复制代码
题目:
需要手动管理 Observer 的列表。
notify() 需要手动遍历所有观察者,不够机动。
可能会出现空指针题目(被观察者销毁后,观察者仍在利用)。
4. 用 Qt 信号与槽实现观察者模式
Qt 提供了一种更强大、更安全的实现方式——
信号(Signal)与槽(Slot)机制
。它本质上就是
观察者模式的扩展
,但更加机动和易用!
信号与槽怎样实现观察者模式?
观察者模式脚色
Qt 信号与槽对应
Subject(被观察者)QObject + SignalObserver(观察者)QObject + Slot通知机制connect()
Qt 实现观察者模式
#include <QObject>
#include <QDebug>
// 被观察者(Subject)
class Subject : public QObject {
Q_OBJECT
signals:
void valueChanged(int newValue); // 信号(事件)
public:
void setValue(int value) {
emit valueChanged(value); // 触发信号,通知观察者
}
};
// 观察者(Observer)
class Observer : public QObject {
Q_OBJECT
public slots:
void onValueChanged(int newValue) {
qDebug() << "Observer received new value:" << newValue;
}
};
int main() {
Subject subject;
Observer observer;
// 连接信号和槽
QObject::connect(&subject, &Subject::valueChanged, &observer, &Observer::onValueChanged);
// 触发事件
subject.setValue(42);
}
复制代码
Qt 信号与槽 vs 传统观察者模式
对比项
传统观察者模式
Qt 信号与槽
观察者管理方式需手动维护列表主动管理触发方式直接调用 update()emit 发送信号线程安全需要手动同步Qt:
ueuedConnection 支持多线程排除毗连需要手动移除观察者disconnect() 轻松解绑
5. 信号与槽让观察者模式更强大
主动管理毗连
,克制空指针错误。
支持跨线程通信
,不需要额外的同步机制。
更机动
:可以在运行时动态毗连和排除毗连。
更易读
:代码清晰,不需要手动维护 std::vector<Observer*>。
6. 观察者模式怎样运用到实际开发中?
1. UI 界面更新
当数据变革时,主动更新 UI 界面(如 QLabel、QProgressBar)。
QObject::connect(&subject, &Subject::valueChanged, ui->label, &QLabel::setText);
复制代码
2. 多线程使命通知主线程
通过 Qt:
ueuedConnection 让后台线程通知主线程革新 UI。
3. 事件驱动开发
Qt 本身就是
事件驱动
的,信号与槽大幅淘汰了回调函数的利用。
7. 总结
观察者模式解决了
对象间的事件通知
题目。
Qt
信号与槽机制
是观察者模式的高级实现,提供
主动管理、类型安全、跨线程支持
。
在 Qt 开发中,几乎所有 UI 组件、后台使命、事件响应都基于
信号与槽
。
你学会了吗?
欢迎光临 IT评测·应用市场-qidao123.com (https://dis.qidao123.com/)
Powered by Discuz! X3.4