【发布时间】:2020-05-18 22:26:39
【问题描述】:
在主循环中,创建了一个 2 x 2 tkinter 网格 第一行的每个单元格中都有一个标签。 在第二行中,两个 Matplotlib 图形与子图一起装箱 两个函数负责动态刷新网格。 他们在一个线程中运行每一个。 第一行(两个标签)很好地被两个函数刷新。 但是,在第二行中什么都没有……没有情节!
from tkinter import *
import threading
import time
from matplotlib.figure import Figure
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg
from matplotlib import style
def read_api1():
n = 0
while 1:
n = n + 1
texte1.config(text="fig1 " + str(n))
ax1.plot([1,2], [12,14])
time.sleep(2)
ax1.cla()
def read_api2():
m = 0
while 1:
m = m + 1
texte2.config(text="fig2 " + str(m))
ax2.plot([.1,.2,.3], [2,4,3])
time.sleep(1)
main = Tk()
style.use("ggplot")
texte1 = Label(main, text="fig1")
texte1.grid(row=0,column=0)
fig1 = Figure(figsize=(2, 2), dpi=112)
ax1 = fig1.add_subplot()
fig1.set_tight_layout(True)
graph = FigureCanvasTkAgg(fig1, master=main)
canvas = graph.get_tk_widget()
canvas.grid(row=1, column=0)
texte2 = Label(main, text="fig2")
texte2.grid(row=0,column=1)
fig2 = Figure(figsize=(2, 2), dpi=112)
ax2 = fig2.add_subplot()
fig2.set_tight_layout(True)
graph = FigureCanvasTkAgg(fig2, master=main)
canvas = graph.get_tk_widget()
canvas.grid(row=1, column=1)
t = threading.Thread(target=read_api1)
t.start()
t = threading.Thread(target=read_api2)
t.start()
main.mainloop()
任何帮助将不胜感激:)
编辑:
更多细节@furas:
read_api2 应该在特定时间从WEB API获取数据。所以你推荐的(after方法)应该有效。read_api1应该从串行端口 (GPIO UART) 获取数据。所以线程将等待可读取的数据。
那样的话,我看不出怎么用after方法
换句话说,问题是:如何在基于异步输入的 tkinter 环境中刷新 matplotlib 图?异步串行数据读取不能在主循环中,所以我把它放在线程中但即使使用graph.draw(),它也不起作用。有什么建议吗?
【问题讨论】:
-
通常 GUI 不喜欢在线程中工作,只有主线程可以更新小部件。
-
我在您的问题中添加了您的新信息。
-
如果您有新信息,请添加到问题中,而不是添加到答案中。在开始时,您应该写下您将从 GPIO 读取数据——它会改变一切。或者现在您必须在新页面上创建新问题,因为这是新问题。
-
现在你必须在线程中运行
GPIO并使用队列向主线程发送数据,主线程必须使用after()定期检查Queue,如果有新数据则它应该显示新的情节。我想我很久以前在 Stackoverflow 上做过这样的事情,也许我在 examples on GitHub -
对于
WEB API- 您可以计算(specific_time - current_time)并将其转换为毫秒并使用after(millisecond, ...)中的结果在特定时间运行函数。
标签: python multithreading matplotlib tkinter