当前位置:   article > 正文

tkinter以多线程方式用matplot绘图崩溃问题_多线程环境下使用matplotlib可能引发的问题导致

多线程环境下使用matplotlib可能引发的问题导致

tkinter中以多线程方式用matplotlib绘图出现程序崩溃问题

  • 需求:需要绘制一幅动态图(大约3000帧左右)。但是数据量太大,约莫绘制到60-200帧不等时,出现程序未响应。

  • 解决:开启线程去解决这个需求

  • 问题:当使用线程,并用matplotlib画图之后,绘制到tkinter窗体上,出现程序直接崩溃

一个以多线程方式用plt绘图到tkinter上程序崩溃的小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.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()
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 运行示例:

    根据代码,点击确定会以线程方式在白框位置输出信息,同时在窗体的右下角出现一幅图像。

  • 点击确定按钮之后

  • 白框位置出现输入之后,过一会还未出现绘图,程序直接闪退

  • 经过测试,发现问题出现在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()
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/小蓝xlanll/article/detail/115917
推荐阅读
相关标签
  

闽ICP备14008679号