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

相关推荐
爱学习的阿磊5 分钟前
使用XGBoost赢得Kaggle比赛
jvm·数据库·python
智航GIS10 分钟前
ArcGIS Python零基础脚本开发教程---1.1 Describe 函数
开发语言·python·arcgis
Dreaming_of_you14 分钟前
pytorch/cv2/pil/torchvision处理图像缩小的最佳方案
人工智能·pytorch·python·opencv
Testopia1 小时前
走一遍 AI 学习之路 —— AI实例系列说明
开发语言·人工智能·python
机 _ 长1 小时前
YOLO26 改进 | 训练策略 | 知识蒸馏 (Response + Feature + Relation)
python·深度学习·yolo·目标检测·机器学习·计算机视觉
草青工作室1 小时前
java-FreeMarker3.4自定义异常处理
java·前端·python
hrrrrb1 小时前
【算法设计与分析】随机化算法
人工智能·python·算法
D___H1 小时前
Part10_编写自己的解释器
python
Zero_to_zero12341 小时前
Claude code系列(一):claude安装、入门及基础操作指令
人工智能·python