赞
踩
需求:需要绘制一幅动态图(大约3000帧左右)。但是数据量太大,约莫绘制到60-200帧不等时,出现程序未响应。
解决:开启线程去解决这个需求
问题:当使用线程,并用matplotlib画图之后,绘制到tkinter窗体上,出现程序直接崩溃
import tkinter as tk import threading # 导入多线程模块 class GUI: def __init__(self): self.root = tk.Tk() self.root.title('演示窗口') self.root.geometry("1024x960+1100+150") self.interface() def interface(self): """"界面编写位置""" self.Button0 = tk.Button(self.root, text="确定", command=self.start) self.Button0.grid(row=0, column=0) self.w1 = tk.Text(self.root, width=80, height=10) self.w1.grid(row=1, column=0) def event(self): '''按钮事件,一直循环''' a = 0 while True: a += 1 self.w1.insert(1.0, str(a) + '\n') self.figure = Figure(figsize=(5, 5), dpi=100) self.subplot = self.figure.add_subplot(1, 1, 1) self.subplot.set(xlim=[0, 20], ylim=[0, 20]) # self.subplot.xaxis.set_ticks(np.arange(0, 26, 1)) self.canvas = tk.Canvas(self.root,bg="red") self.canvas_fig = FigureCanvasTkAgg(self.figure, master=self.canvas) # 3.2 将这个中间件放到图像绘制 self.subplot.plot(np.array(range(10))) self.canvas_fig.draw() self.canvas.place(relx=0.2, rely=0.2, relwidth=0.8, relheight=0.8) break def start(self): self.T = threading.Thread(target=self.event) # 多线程 self.T.setDaemon(True) # 线程守护,即主进程结束后,此线程也结束。否则主进程结束子进程不结束 self.T.start() # 启动 if __name__ == '__main__': a = GUI() a.root.mainloop()
运行示例:
根据代码,点击确定会以线程方式在白框位置输出信息,同时在窗体的右下角出现一幅图像。
点击确定按钮之后
白框位置出现输入之后,过一会还未出现绘图,程序直接闪退
经过测试,发现问题出现在self.canvas_fig.draw()
。每当运行到此处时,程序崩溃
解决程序崩溃方案:执行draw()方法时,用after()方式。如:self.root.after(100, self.canvas_fig.draw)
改动后的demo代码
import tkinter as tk import threading # 导入多线程模块 class GUI: def __init__(self): self.root = tk.Tk() self.root.title('演示窗口') self.root.geometry("1024x960+1100+150") self.interface() def interface(self): """"界面编写位置""" self.Button0 = tk.Button(self.root, text="确定", command=self.start) self.Button0.grid(row=0, column=0) self.w1 = tk.Text(self.root, width=80, height=10) self.w1.grid(row=1, column=0) def event(self): '''按钮事件,一直循环''' a = 0 while True: a += 1 self.w1.insert(1.0, str(a) + '\n') self.figure = Figure(figsize=(5, 5), dpi=100) self.subplot = self.figure.add_subplot(1, 1, 1) self.subplot.set(xlim=[0, 20], ylim=[0, 20]) # self.subplot.xaxis.set_ticks(np.arange(0, 26, 1)) self.canvas = tk.Canvas(self.root,bg="red") self.canvas_fig = FigureCanvasTkAgg(self.figure, master=self.canvas) # 3.2 将这个中间件放到图像绘制 self.subplot.plot(np.array(range(10))) self.root.after(100, self.canvas_fig.draw) # self.canvas_fig.draw() self.canvas.place(relx=0.2, rely=0.2, relwidth=0.8, relheight=0.8) break def start(self): self.T = threading.Thread(target=self.event) # 多线程 self.T.setDaemon(True) # 线程守护,即主进程结束后,此线程也结束。否则主进程结束子进程不结束 self.T.start() # 启动 if __name__ == '__main__': a = GUI() a.root.mainloop()
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。