我有以下python代码(在PyCharm中),我用来从Arduino
板读取数据。读数本身很好。我在代码的tkinter部分遇到以下两个问题:
close_plot
时,确实是图形窗口
关闭,不久之后才重新开放。我认为问题在于Top.after
,因为它在mainloop()
内持续运行,因此read_data
功能会不断更新。我怎么能绕过这个?
import serial
from tkinter import *
from matplotlib import pyplot as plt
Top = Tk()
ser = serial.Serial('COM3', baudrate=9600, timeout=1)
x = []
y = []
def read_data():
plt.ion()
new_value = ser.readline().decode('ascii')
if new_value == '':
pass
else:
y.append(eval(new_value[:-2]))
x.append(len(y) - 1)
plt.plot(x, y, 'r-')
plt.show()
plt.pause(0.0001)
Top.after(100, read_data)
def close_plot():
plt.close()
global x, y
x = []
y = []
def quit():
Top.destroy()
Button(Top, text='Read', command=read_data).pack()
Button(Top, text='Close plot', command=close_plot).pack()
Button(Top, text='Quit', command=quit).pack()
Top.after(100, read_data)
mainloop()
编辑:按下read_data
按钮时,我收到以下警告:
C:\ProgramData\Anaconda3\lib\site-packages\matplotlib\backend_bases.py:2445: MatplotlibDeprecationWarning: Using default event loop until function specific to this GUI is implemented warnings.warn(str, mplDeprecation)
答案 0 :(得分:1)
首先,删除该行:
Top.after(100, read_data)
在mainloop()
furas建议之前立即
然后添加after_cancel
方法以每100毫秒停止调用read_data
,但为了实现这一点,我们需要首先将方法内部使用的after
分配给全局变量:
func_id = Top.after(100, read_data)
然后最终在after_cancel
中致电close_plot
:
Top.after_cancel(func_id)
您的代码应如下所示:
import serial
from tkinter import *
from matplotlib import pyplot as plt
Top = Tk()
ser = serial.Serial('COM3', baudrate=9600, timeout=1)
x = []
y = []
func_id = None
def read_data():
global func_id
plt.ion()
new_value = ser.readline().decode('ascii')
if new_value == '':
pass
else:
y.append(eval(new_value[:-2]))
x.append(len(y) - 1)
plt.plot(x, y, 'r-')
plt.show()
plt.pause(0.0001)
func_id = Top.after(100, read_data)
def close_plot():
global func_id
#to no longer update the plot
Top.after_cancel(func_id)
plt.close()
global x, y
del x[:]
del y[:]
def quit():
Top.destroy()
Button(Top, text='Read', command=read_data).pack()
Button(Top, text='Close plot', command=close_plot).pack()
Button(Top, text='Quit', command=quit).pack()
mainloop()