如何在不同的线程中将matplotlib图形绘制到tkinter画布上

ftf50wuq  于 2023-06-30  发布在  其他
关注(0)|答案(1)|浏览(120)

我想用tkinter GUI在python应用程序中显示matplotlib图。为了避免在创建图形并将其绘制到UI时阻塞UI功能,必须在另一个线程中完成此操作。我如何在一个不同于包含tkinter根和框架的线程中绘制情节?
我试过使用线程模块,并设法在另一个线程中创建一个图形。然而,当我尝试创建一个画布与数字的应用程序崩溃和输出'警告:未在main()线程中创建QApplication。'
进口

from tkinter import *
from tkinter import ttk

import matplotlib
import matplotlib.pyplot as plt
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg

from threading import Thread

现在一切都在同一个类中。我在构造函数中创建根、主机和按钮

def __init__(self):
    # Creates root and mainframe
    self.root = Tk()
    self.mainframe = ttk.Frame(self.root, padding="3 3 12 12")
    self.mainframe.grid(column=0, row=0, sticky=(N, W, E, S))

    # Creates button that runs 'handle_input_change'-method on click
    ttk.Button(self.mainframe, text="Show graph", 
    command=self.handle_input_change).grid(column=3, row=4, sticky=E)

单击按钮时运行的方法

def handle_input_change(self, *args):
    # Starts another thread running the 'plot_current_data'-method
    thread = Thread(target = self.plot_current_data)
    thread.start()
def plot_current_data(self):
    fig = # ... (irrelevant, could be any matplotlib figure)

    # This is what makes the application crash and output the warning message
    canvas = FigureCanvasTkAgg(fig, master=self.mainframe)
    canvas.draw()
    canvas.get_tk_widget().grid(column=1, row=5, rowspan=10, sticky=W)

当我在同一个线程中运行所有这些代码时,上面的代码确实显示了该图。

z9zf31ra

z9zf31ra1#

对我来说,首先在主线上创建画布。然后可以在另一个线程上调用canvas_tkagg.draw()。Python 3.11.1 / Windows10

相关问题