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 函数,然后立即返回不阻塞当前继续执行接下来的代码。这是一个非阻塞的定时任务。

相关推荐
千里码aicood6 分钟前
flask-基于注意力机制的异常流量检测与自动防御系统
后端·python·flask
维克兜率天8 分钟前
4.3.2.1 日常监控:上线只是开始
服务器·数据库·python·区块链·php·量化
the局外人15 分钟前
学习 FastAPI 的 Day 2:用异步 ORM 完成增删改查
后端·python·fastapi
智搜广告17 分钟前
GEO优化公司怎么选?智搜广告从三个维度帮你判断
大数据·人工智能·python·elasticsearch·microsoft·geo
wanglei20070828 分钟前
软件架构设计中,各个组件之间的通信方式有哪些?
python
会飞的拖把34 分钟前
Python 面向对象编程详解:从类与对象到动态属性方法
开发语言·python
微小冷40 分钟前
Python CasADi初步教程
python·控制·模型预测·casadi·符号表达式·sx
cpolar技术支持1 小时前
requirements.txt 能安装不等于安全:用 pip-audit 检查 Python 依赖,cpolar 临时分享脱敏报告
python·cpolar·requirements·依赖安全·pip-audit
测试19981 小时前
Jmeter接口自动化生成测试报告html格式详解
自动化测试·python·测试工具·jmeter·职场和发展·测试用例·接口测试
pjj198541 小时前
Hadoop-python中使用大数据
大数据·hadoop·python