1 分钟后标签图片和串行超时的 Tkinter 刷新问题
Tkinter refresh problem with label picturre and serial timeout after 1 minutes
我正在尝试从 arduino 获取串行数据数组,并将它们用作我 Raspberry Pi 中带有 Python3 的标签的坐标 3. 我可以使用串行获取数组并将标签作为我想要。程序有效。但
第一个问题是我可以看到闪烁,并且闪烁的延迟时间随着时间的推移变得最糟。
第二个问题是程序在几分钟后停止工作。
我尝试了 ser.flushInput() 并且我在每个地方都清除了我的数组,结果是一样的。
from tkinter import *
import serial
root = Tk()
root.geometry("1024x600")
ser = serial.Serial('/dev/ttyAMA0',115200)
ser.timeout=None
data=[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]
data1=[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]
image=[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15]
label=[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15]
x1=[210,210,210,370,370,370,530,530,530,690,690,690,850,850,850,850]
y1=[440,325,75,440,325,75,440,325,75,440,325,75,440,325,200,75]
image_gri=PhotoImage(file="/home/pi/python/gri.gif")
image_kirmizi = PhotoImage(file="/home/pi/python/kirmizi.gif")
image_yesil = PhotoImage(file="/home/pi/python/yesil.gif")
def kontrol():
data=[]
ser.flush()
ser.flushInput()
data = ser.read(32)
#print(data)
for i in range(0,16):
if data[i]==49 and data[i+16]==49:
image[i]=image_yesil
label[i] = Label(root, image=image[i])
label[i].place(x=x1[i],y=y1[i])
elif data[i]==49 and data[i+16]==48:
image[i]=image_kirmizi
label[i] = Label(root, image=image[i])
label[i].place(x=x1[i],y=y1[i])
else :
image[i]=image_gri
label[i] = Label(root, image=image[i])
label[i].place(x=x1[i],y=y1[i])
ser.flush()
ser.flushInput()
root.after(50,kontrol)
root.update()
kontrol()
#root.after(50,kontrol)
mainloop()
我希望程序工作长达 12 小时并且在工作时看不到闪烁。
问题是您在每个 运行 中添加了 16 个 Label 小部件,它们保存在内存中并每次都被处理。旧标签永远不会被删除。
要解决此问题,您可以在创建新标签时使用 label[i].destroy()
删除之前的标签。更好的是只更新现有标签而不是创建新标签,使用 label[i].config(image=...)
.
下面是一个完整的示例(注释掉了一些代码,并使用随机数据和虚拟图像代替,因此任何使用 Python 3 的人都可以 运行 这没有外部依赖):
import random
from tkinter import *
# import serial
root = Tk()
root.geometry("1024x600")
# ser = serial.Serial('/dev/ttyAMA0', 115200)
# ser.timeout = None
# If you have the images, use this:
#IMAGE_GRI = PhotoImage(file="/home/pi/python/gri.gif")
#IMAGE_KIRMIZI = PhotoImage(file="/home/pi/python/kirmizi.gif")
#IMAGE_YESIL = PhotoImage(file="/home/pi/python/yesil.gif")
# Otherwise, create some dummy images for demonstration purposes:
WIDTH = 64
HEIGHT = 64
DATA = ','.join(['0x00' for i in range(WIDTH * HEIGHT // 8)])
BITMAP = '#define im_width %d\n#define im_height %d\nstatic char im_bits[] = {\n%s\n};' % (WIDTH, HEIGHT, DATA)
IMAGE_GRI = BitmapImage(data=BITMAP, background="grey")
IMAGE_KIRMIZI = BitmapImage(data=BITMAP, background="red")
IMAGE_YESIL = BitmapImage(data=BITMAP, background="green")
# Initialize with grey images (you may choose a different image, of course)
label = [Label(root, image=IMAGE_GRI) for i in range(16)]
x1 = [210, 210, 210, 370, 370, 370, 530, 530, 530, 690, 690, 690, 850, 850, 850, 850]
y1 = [440, 325, 75, 440, 325, 75, 440, 325, 75, 440, 325, 75, 440, 325, 200, 75]
# Place the images only once:
for i in range(16):
label[i].place(x=x1[i], y=y1[i])
def kontrol():
data = []
# ser.flush()
# ser.flushInput()
# data = ser.read(32)
# Create random data for demonstration purposes:
data = [random.choice((48, 49)) for i in range(32)]
#print(data)
for i in range(16):
if data[i] == 49 and data[i+16] == 49:
label[i].config(image=IMAGE_YESIL) # update image!
elif data[i] == 49 and data[i+16] == 48:
label[i].config(image=IMAGE_KIRMIZI) # update image!
else:
label[i].config(image=IMAGE_GRI) # update image!
# ser.flush()
# ser.flushInput()
root.after(50, kontrol)
# root.update() # Not necessary! Use root.update_idletasks() if necessary.
kontrol()
mainloop()
我正在尝试从 arduino 获取串行数据数组,并将它们用作我 Raspberry Pi 中带有 Python3 的标签的坐标 3. 我可以使用串行获取数组并将标签作为我想要。程序有效。但 第一个问题是我可以看到闪烁,并且闪烁的延迟时间随着时间的推移变得最糟。 第二个问题是程序在几分钟后停止工作。
我尝试了 ser.flushInput() 并且我在每个地方都清除了我的数组,结果是一样的。
from tkinter import *
import serial
root = Tk()
root.geometry("1024x600")
ser = serial.Serial('/dev/ttyAMA0',115200)
ser.timeout=None
data=[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]
data1=[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]
image=[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15]
label=[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15]
x1=[210,210,210,370,370,370,530,530,530,690,690,690,850,850,850,850]
y1=[440,325,75,440,325,75,440,325,75,440,325,75,440,325,200,75]
image_gri=PhotoImage(file="/home/pi/python/gri.gif")
image_kirmizi = PhotoImage(file="/home/pi/python/kirmizi.gif")
image_yesil = PhotoImage(file="/home/pi/python/yesil.gif")
def kontrol():
data=[]
ser.flush()
ser.flushInput()
data = ser.read(32)
#print(data)
for i in range(0,16):
if data[i]==49 and data[i+16]==49:
image[i]=image_yesil
label[i] = Label(root, image=image[i])
label[i].place(x=x1[i],y=y1[i])
elif data[i]==49 and data[i+16]==48:
image[i]=image_kirmizi
label[i] = Label(root, image=image[i])
label[i].place(x=x1[i],y=y1[i])
else :
image[i]=image_gri
label[i] = Label(root, image=image[i])
label[i].place(x=x1[i],y=y1[i])
ser.flush()
ser.flushInput()
root.after(50,kontrol)
root.update()
kontrol()
#root.after(50,kontrol)
mainloop()
我希望程序工作长达 12 小时并且在工作时看不到闪烁。
问题是您在每个 运行 中添加了 16 个 Label 小部件,它们保存在内存中并每次都被处理。旧标签永远不会被删除。
要解决此问题,您可以在创建新标签时使用 label[i].destroy()
删除之前的标签。更好的是只更新现有标签而不是创建新标签,使用 label[i].config(image=...)
.
下面是一个完整的示例(注释掉了一些代码,并使用随机数据和虚拟图像代替,因此任何使用 Python 3 的人都可以 运行 这没有外部依赖):
import random
from tkinter import *
# import serial
root = Tk()
root.geometry("1024x600")
# ser = serial.Serial('/dev/ttyAMA0', 115200)
# ser.timeout = None
# If you have the images, use this:
#IMAGE_GRI = PhotoImage(file="/home/pi/python/gri.gif")
#IMAGE_KIRMIZI = PhotoImage(file="/home/pi/python/kirmizi.gif")
#IMAGE_YESIL = PhotoImage(file="/home/pi/python/yesil.gif")
# Otherwise, create some dummy images for demonstration purposes:
WIDTH = 64
HEIGHT = 64
DATA = ','.join(['0x00' for i in range(WIDTH * HEIGHT // 8)])
BITMAP = '#define im_width %d\n#define im_height %d\nstatic char im_bits[] = {\n%s\n};' % (WIDTH, HEIGHT, DATA)
IMAGE_GRI = BitmapImage(data=BITMAP, background="grey")
IMAGE_KIRMIZI = BitmapImage(data=BITMAP, background="red")
IMAGE_YESIL = BitmapImage(data=BITMAP, background="green")
# Initialize with grey images (you may choose a different image, of course)
label = [Label(root, image=IMAGE_GRI) for i in range(16)]
x1 = [210, 210, 210, 370, 370, 370, 530, 530, 530, 690, 690, 690, 850, 850, 850, 850]
y1 = [440, 325, 75, 440, 325, 75, 440, 325, 75, 440, 325, 75, 440, 325, 200, 75]
# Place the images only once:
for i in range(16):
label[i].place(x=x1[i], y=y1[i])
def kontrol():
data = []
# ser.flush()
# ser.flushInput()
# data = ser.read(32)
# Create random data for demonstration purposes:
data = [random.choice((48, 49)) for i in range(32)]
#print(data)
for i in range(16):
if data[i] == 49 and data[i+16] == 49:
label[i].config(image=IMAGE_YESIL) # update image!
elif data[i] == 49 and data[i+16] == 48:
label[i].config(image=IMAGE_KIRMIZI) # update image!
else:
label[i].config(image=IMAGE_GRI) # update image!
# ser.flush()
# ser.flushInput()
root.after(50, kontrol)
# root.update() # Not necessary! Use root.update_idletasks() if necessary.
kontrol()
mainloop()