Tkinter GUI多进程间通信与显示刷新【mutiprocessing、threading、psutil】
Tkinter作为一个纯GUI不具备类似Qt、MFC等框架的消息传递能力,只能通过Tkinter类对象对显示值进行更新;
开发GUI程序一定是避免不了多线程和多进程的开发,当需要对运行进程灵活控制如暂停和恢复,则需引入库psutil进行进程的挂起和恢复,至于多进程threading,根本不支持这些操作;
当Tkinter GUI需要与进程进行通信并刷新界面时,则需要去接受来自进程的消息,使用mutiprocessing提供的PiPe管道即可,由于接收是阻塞的,于是需要分立一个线程去接收,为什么不用进程?进程间对象空间不一致,若用共享内存就不能进行复杂的对象传递,而线程是处于同一个对象空间内的;
GUI_Flush
负责数据接收与界面刷新
注意设置线程和进程的守护进程和线程,不然退出GUI时会有线程或者进程残留无法全部退出;
class Window:
对应功能界面显示与刷新
class T_main:
对应信息发送与后台程序的执行
附Code如下;
import multiprocessing import threading import time import tkinter as tk import psutil class Window: def __init__(self) -> None: self.win=tk.Tk() self.Var_Label = tk.StringVar(self.win,"INIT") self.Var_Button=tk.StringVar(self.win,"Start") self.ppp=multiprocessing.Pipe() #博客园:https://www.cnblogs.com/hardfood/ bili:崩析 def GUI_Design(self): tk.Label(self.win,textvariable=self.Var_Label).grid(column=0,row=0) tk.Button(self.win,textvariable=self.Var_Button,command=self.multiprocess_run).grid(column=1,row=0) #博客园:https://www.cnblogs.com/hardfood/ bili:崩析 def GUI_Flush(self): while True: data = self.ppp[1].recv() self.Var_Label.set(data) #博客园:https://www.cnblogs.com/hardfood/ bili:崩析 def run(self): self.GUI_Design() tr=threading.Thread(target=self.GUI_Flush) tr.setDaemon(True) tr.start() self.win.mainloop() #博客园:https://www.cnblogs.com/hardfood/ bili:崩析 def multiprocess_run(self): if self.Var_Button.get()=="Start": test_run = T_main(self.ppp[0]) tr=multiprocessing.Process(target=test_run.run) tr.daemon=True tr.start() self.p = psutil.Process(tr.pid) self.Var_Button.set("Pause") elif self.Var_Button.get()=="Pause": self.p.suspend() self.Var_Button.set("Resure") elif self.Var_Button.get()=="Resure": self.p.resume() self.Var_Button.set("Pause") #博客园:https://www.cnblogs.com/hardfood/ bili:崩析 class T_main: def __init__(self,pip:multiprocessing.Pipe()[0]) -> None: self.pip = pip #博客园:https://www.cnblogs.com/hardfood/ bili:崩析 def run(self): count=0 while True: self.pip.send(str(count)) count+=1 time.sleep(1) #博客园:https://www.cnblogs.com/hardfood/ bili:崩析 if __name__=="__main__": xe = Window() xe.run()
运行效果如下;
关于Pyintsaller 多进程打包多个窗口问题
需在程序运行前加入函数
multiprocessing.freeze_support()
大概意思是,linux和windows系统底层实现不同,
linux想创建新的进程直接fork()出子进程就行,
而windows则是直接创建出一个新进程来模拟子进程
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!