Python 更新Tkinter框架中的Matplotlib绘图

Python 更新Tkinter框架中的Matplotlib绘图,python,matplotlib,tkinter,Python,Matplotlib,Tkinter,我试图在tkinter gui中从串行端口绘制数据。仅当特定数据包来自串行数据包时,才应绘制和更新该图。 我可以解析新的传入数据并更新GUI(文本区域)。但是当我从“update_gui”线程调用“plot()”函数时,程序退出,我得到 “进程已完成,退出代码为-1073741819(0xC0000005)” 信息 相反,如果我从其他地方调用“plot()”(命令按钮,或仅在mainloop()之前),将生成并显示绘图 以下是守则的相关部分: import threading import t

我试图在tkinter gui中从串行端口绘制数据。仅当特定数据包来自串行数据包时,才应绘制和更新该图。 我可以解析新的传入数据并更新GUI(文本区域)。但是当我从“update_gui”线程调用“plot()”函数时,程序退出,我得到

“进程已完成,退出代码为-1073741819(0xC0000005)”

信息

相反,如果我从其他地方调用“plot()”(命令按钮,或仅在mainloop()之前),将生成并显示绘图

以下是守则的相关部分:


import threading
import tkinter as tk
import tkinter.scrolledtext as st
import rx_seriale as rx_ser
from matplotlib.figure import Figure
from matplotlib.backends.backend_tkagg import (FigureCanvasTkAgg, NavigationToolbar2Tk)
import queue

running = True
serial_data = ''
filter_data = ''
update_period = 5
serial_object = None
gui = tk.Tk()
gui.title("UART Interface")
my_queue = queue.Queue()
t1 = ''


def plot(valori):
    global frame_plot1

    try:
        # the figure that will contain the plot
        fig = Figure(figsize=(4.5, 4), dpi=100)

        # adding the subplot
        plot1 = fig.add_subplot(111)

        #dummy values
        y = [i ** 2 for i in range(101)]

        # plotting the graph
        plot1.plot(y)

        # creating the Tkinter canvas
        # containing the Matplotlib figure
        canvas = FigureCanvasTkAgg(fig, master=frame_plot1)
        canvas.draw()

        # placing the canvas on the Tkinter window
        canvas.get_tk_widget().pack()

        # creating the Matplotlib toolbar
        #toolbar = NavigationToolbar2Tk(canvas, frame_plot1)
        #toolbar.update()

        # placing the toolbar on the Tkinter window
        #canvas.get_tk_widget().pack()
    except Exception as e:
        print('Errore:' + str(e))


def update_gui():
    global filter_data
    global update_period
    global my_queue
    global type_test, test_status,flag

    while (1):

        data = my_queue.get(block=True)

        text.insert('end', test_status[data[0]] + " - " + type_test[data[1]])
        text.insert('end', '\n')
        text.see('end')

        if (data[1] == 6):
            plot(1)


if __name__ == "__main__":
   
'''
...
all the stuff for design TK windows
...
'''

    # threads
    t2 = threading.Thread(target=update_gui)
    t2.daemon = True
    t2.start()

    # mainloop
    gui.geometry('1000x500')
    gui.mainloop()

出了什么问题?谢谢。

除了最初创建
tk.tk()
window@TheLizzard:好的,但是为什么文本区域更新方法有效?我忘了提到在“canvas.draw()”调用之前,“plot()”函数是正确执行的。当您从其他线程调用其方法时,
tkinter
的一些(或大部分?)行为是未定义的,因此您不能期望任何结果。您应该改用
.after
循环。有关更多信息,请访问@TheLizzard:谢谢您的评论。我尝试了
之后,如果我没有误解,这个方法只执行一次。实际上,我的问题是触发一个Tkinter更新事件,该事件不是由按钮或按键等引发的,而是来自串行接收器线程。我可以通过带有队列的线程传递数据,但如何以编程方式引发tk事件呢。尝试将
my\u queue.get(block=True)
更改为
my\u queue.get(block=False)
。另外,如果在
回调中使用
.after
。在
回调之后,可以进行循环。看看