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