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

相关推荐
amazinging12 分钟前
北京-4年功能测试2年空窗-报培训班学测开-第四十四天
python·学习·appium
UrbanJazzerati23 分钟前
Xlwings安装报错:Connection timed out & WinError 32?一招解决你的安装难题!
python
Tipriest_25 分钟前
Python异常类型介绍
开发语言·python·异常
前端付豪30 分钟前
21、用 Python + Pillow 实现「朋友圈海报图生成器」📸(图文合成 + 多模板 + 自动换行)
后端·python
猿榜1 小时前
魔改编译-永久解决selenium痕迹(二)
javascript·python
广东数字化转型1 小时前
java jar 启动应用程序
开发语言·python
费弗里2 小时前
Python全栈应用开发利器Dash 3.x新版本介绍(4)
python·dash
辣辣y2 小时前
python基础day08
开发语言·python
花海如潮淹2 小时前
硬件产品研发管理工具实战指南
前端·python
张彦峰ZYF2 小时前
快速掌握Python编程基础
python