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

相关推荐
Psycho_MrZhang42 分钟前
高并发服务设计思路
python
多米Domi0111 小时前
0x3f 第21天 三更java进阶1-35 hot100普通数组
java·python·算法·leetcode·动态规划
小程故事多_801 小时前
从零吃透PyTorch,最易懂的入门全指南
人工智能·pytorch·python
Keep_Trying_Go2 小时前
基于无监督backbone无需训练的类别无关目标统计CountingDINO算法详解
人工智能·python·算法·多模态·目标统计
weixin_433179333 小时前
python - for循环,字符串,元组基础
开发语言·python
^哪来的&永远~3 小时前
Python 轻量级 UI:EEG 与 fNIRS 预处理图形界面
python·可视化·功能连接·eeg·mne·fnirs·eeglab
AI大佬的小弟3 小时前
Python基础(11):Python中函数参数的进阶模式详解
python·lambda函数·函数的参数解释·函数的参数进阶·位置参数·关键词参数·匿名函数与普通函数
智算菩萨3 小时前
Python可以做哪些小游戏——基于Python 3.13最新特性的游戏开发全指南(15万字超长文章,强烈建议收藏阅读)
python·pygame
智航GIS3 小时前
9.1 多线程入门
java·开发语言·python
nvd113 小时前
FastMCP 开发指南: 5分钟入门
人工智能·python