信号与槽Signals SlotsPython 总结0. 概括信号与槽是一种「事件发布 — 订阅」模式一个对象发出 “信号”其他对象通过 “槽” 来响应两者完全解耦不需要互相知道对方存在。它不是 Python 内置语法而是一种编程设计模式广泛用于GUI 框架PyQt/PySide异步框架游戏逻辑插件系统组件化、模块化架构1. 核心概念1.1 信号Signal本质一个 “事件发生了” 的通知作用当某个状态变化、某个动作完成时主动广播出去特点只负责 “发通知”不关心谁接收可以携带参数数据可以被多个槽同时监听1.2 槽Slot本质一个准备好接收信号、并执行逻辑的函数 / 方法作用信号触发时自动被调用特点一个槽可以监听多个信号槽可以是普通函数、实例方法、lambda 等执行时机由信号触发决定1.3 连接Connect把信号和槽绑定在一起的过程。有无信号发射是否有绑定的槽?自动调用所有绑定的槽无操作信号发射 → 自动调用所有绑定的槽2. 为什么要用信号与槽2.1 彻底解耦就像两个陌生人不需要知道对方的联系方式也能传递消息一样发送消息的一方不需要保存接收方的任何信息接收消息的一方也不用知道消息是谁发过来的2.2 一对多、多对一灵活通信信号和槽的通信方式特别灵活支持一个事件触发多个处理动作多个不同事件触发同一个处理动作一个事件触发后还能接着触发其他事件类似接力2.3 逻辑清晰把 “发生了什么事” 和 “具体怎么处理” 分开就像把做饭和洗碗分工一样让代码更容易理解和维护。2.4 适合异步 / 事件驱动这种机制特别适合下面这些场景图形界面程序网络编程消息队列处理状态机控制3. 用 Python 手写一个极简信号槽不依赖任何库纯 Python 实现帮助你彻底理解底层。class Signal: def __init__(self): self.slots [] # 保存所有槽函数 # 连接槽 def connect(self, slot): if slot not in self.slots: self.slots.append(slot) # 断开槽 def disconnect(self, slot): if slot in self.slots: self.slots.remove(slot) # 发射信号触发所有槽 def emit(self, *args, **kwargs): for slot in self.slots: slot(*args, **kwargs)使用示例# 槽函数 def on_message(msg): print(f收到消息{msg}) def on_another(msg): print(f另一个槽也收到{msg}) # 创建信号 signal Signal() # 连接槽 signal.connect(on_message) signal.connect(on_another) # 发射信号 signal.emit(Hello Signal Slot)输出收到消息Hello Signal Slot 另一个槽也收到Hello Signal Slot原理总结信号本质 维护一个函数列表发射 遍历调用列表里的所有函数4. 进阶知识点4.1 信号可以带任意参数signal.emit(下载完成, 100, True)槽只需要对应参数即可def slot(status, percent, ok): ...4.2 一个信号可以绑定多个槽一对多signal.connect(slot1) signal.connect(slot2) signal.connect(slot3)4.3 一个槽可以绑定多个信号多对一signal1.connect(common_slot) signal2.connect(common_slot) signal3.connect(common_slot)4.4 信号可以连接信号转发signal_a.connect(signal_b.emit) signal_b.connect(real_slot) signal_a.emit(...) # 最终触发 real_slot4.5 可以断开连接signal.disconnect(on_message)4.6 可以临时阻塞信号实际库中一般提供block()blocked临时禁用信号触发避免频繁触发导致性能问题。4.7 线程安全问题手写版不是线程安全的。真正库PyQt、PySide、asyncio 信号会加锁队列化跨线程安全调度登录成功 → 发信号加载完成 → 发信号错误发生 → 发信号5. 信号槽 vs 其他模式5.1 对比回调函数回调一对一信号槽一对多、多对一、可解绑、可转发更灵活、更易扩展。5.2 对比观察者模式信号槽就是观察者模式的 Qt/Python 风格封装Subject 信号发送者Observer 槽notify emit5.3 对比事件总线Event Bus信号槽是局部事件总线事件总线是全局信号槽6. 总结信号 事件通知槽 事件处理函数连接 绑定关系emit 触发执行核心价值解耦、灵活、可扩展适用场景GUI、异步、插件、多线程、状态管理