Python 类似iOS中Notification广播功能的机制-Observer

1.需求背景:

为了实现子线程通知主线程刷新UI功能,并且不阻塞其他线程的执行.

2.技术调研

在 Python 中,你可以使用多种方式实现类似于 iOS notification 的通知机制。例如,你可以使用标准库中的 Observer 设计模式,或者使用一些第三方库如 pydispatcherblinker

3.代码实现

下面是一个使用 Observer 模式来模拟通知的简单示例:

3.1 tkinter(系统GUI)
python 复制代码
import threading
import time
import tkinter as tk
import queue

class EventNotifier(threading.Thread):
    def __init__(self, event_queue):
        threading.Thread.__init__(self)
        self.event_queue = event_queue

    def run(self):
        while True:
            time.sleep(2)
            self.event_queue.put("Event")

class MainWindow(tk.Tk):
    def __init__(self, event_queue):
        tk.Tk.__init__(self)
        self.event_queue = event_queue
        self.label = tk.Label(self, text='Waiting for event')
        self.label.pack()
        self.check_event_queue()

    def check_event_queue(self):
        try:
            event = self.event_queue.get_nowait()
            if event:
                self.label['text'] = 'Received event: ' + str(event)
        except queue.Empty:
            pass
        # tk定时器,100毫秒后继续执行self.check_event_queue函数,这个函数的执行不会阻塞前面的程序。
        self.after(100, self.check_event_queue)


if __name__ == "__main__":
    event_queue = queue.Queue()
    notifier = EventNotifier(event_queue)
    notifier.start()

    window = MainWindow(event_queue)
    window.mainloop()

上述代码中,EventNotifier线程每隔2秒往队列中添加一个事件,MainWindow是一个Tkinter窗口,它每隔100毫秒检查一次队列中是否有新的事件,如果有,就更新标签的文本。

注意:为了线程安全,我们使用了queue.Queue这样的线程安全的队列来作为事件的传递。

3.2 pyQt(三方GUI)
python 复制代码
import threading
import time
import tkinter as tk
import queue

class EventNotifier(threading.Thread):
    def __init__(self, event_queue):
        threading.Thread.__init__(self)
        self.event_queue = event_queue

    def run(self):
        while True:
            time.sleep(2)
            self.event_queue.put("Event")

class MainWindow_pyqt(QLabel):
    def __init__(self, event_queue):
        super().__init__('Waiting for task...')
        self.event_queue = event_queue
        self.check_event_queue()

    def check_event_queue(self):
        try:
            event = self.event_queue.get_nowait()
            if event:
                self.setText(str(event))
                jmlog(f'处理通知{str(event)}')
        except queue.Empty:
            pass
        # 单次触发的定时器,1s后继续执行self.check_event_queue函数,这个函数的执行不会阻塞前面的程序。
        QTimer.singleShot(1000, self.check_event_queue)

if __name__ == "__main__":
    app = QApplication(sys.argv)
    event_queue = queue.Queue()
    
    notifier = EventNotifier(event_queue)
    notifier.start()

    window = MainWindow_pyqt(event_queue)
    window.show()
    sys.exit(app.exec_())

QTimer.singleShot(1000, self.check_queue) 语句的原理是:在调用这个语句的 1 秒后,执行 self.check_queue 函数,然后立即返回不阻塞当前继续执行接下来的代码。这是一个非阻塞的定时任务。

相关推荐
我的xiaodoujiao40 分钟前
API 接口自动化测试详细图文教程学习系列16--项目实战演练3
python·学习·测试工具·pytest
ID_1800790547344 分钟前
Python 实现亚马逊商品详情 API 数据准确性校验(极简可用 + JSON 参考)
java·python·json
时空系1 小时前
第10篇:继承扩展——面向对象编程进阶 python中文编程
开发语言·python·ai编程
CHANG_THE_WORLD2 小时前
python 批量终止进程exe
开发语言·python
liann1192 小时前
3.2_红队攻击框架--MITRE ATT&CK‌
python·网络协议·安全·网络安全·系统安全·信息与通信
云天AI实战派3 小时前
AI 智能体问题排查指南:ChatGPT、API 调用到 Agent 上线失灵的全流程修复手册
大数据·人工智能·python·chatgpt·aigc
我的xiaodoujiao3 小时前
API 接口自动化测试详细图文教程学习系列15--项目实战演练2
python·学习·测试工具·pytest
多思考少编码4 小时前
PAT甲级真题1001 - 1005题详细题解(C++)(个人题解)
c++·python·最短路·pat·算法竞赛
ZhengEnCi4 小时前
M5-markconv自定义CSS样式指南 📝
前端·css·python
ZhengEnCi5 小时前
M4-更新日志v0.1.3-Mermaid图表支持 📝
python