我有一个我为Raspberry Pi项目编写的python脚本,脚本每秒从微米读取一个值,并将此值存储为TkInter StringVar(http://effbot.org/tkinterbook/variable.htm)
我想要发生的是,该字符串作为标签显示在UI上,并在值更改时在UI上更新。
我选择使用Tkinter stringvar而不是标准字符串,因为我认为Tkinter会在UI上自动更新,但它似乎不起作用。 目前,该脚本不会显示任何标签,并且在 show 设置 virtual_reading 时不会更新。
从我读过的其他线程中,Tkinter方法update_idletasks()应该强制窗口更新,但是我无法让它工作。
任何人都可以就我出错的地方提供任何指导吗? 这是我第一次使用Python,很抱歉,如果这很简单。
import datetime
import csv
from tkinter import *
from tkinter import messagebox
import time
import pigpio
import os
os.system("sudo pigpiod")
root = Tk()
winx = 480
winy = 320
CLOCK=21
DATA=20
g_level=0
g_reading=0
g_bits=0
pi = pigpio.pi()
virtual_reading = StringVar()
def go():
global cb1
global cb2
cb1 = pi.callback(DATA, pigpio.EITHER_EDGE, cbf)
cb2 = pi.callback(CLOCK, pigpio.EITHER_EDGE, cbf)
root.after(1000 ,go)
def show(bits, value):
inch = value & (1<<23)
minus = value & (1<<20)
value = value & 0xfffff
if inch:
reading = value / 2000.0
units = "in"
else:
reading = value / 100.0
units = "mm"
if minus:
sign = "-"
else:
sign = ""
global virtual_reading
virtual_reading = StringVar()
virtual_reading.set("{} {:.3f} {}".format(sign, reading, units))
print(virtual_reading.get())
cb2.cancel()
cb1.cancel()
def measure(event=None):
todays_date = datetime.date.today()
try:
get_tool_no = int(tool_no_entry.get())
if get_tool_no <= 0:
messagebox.showerror("Try Again","Please Enter A Number")
else:
with open("thickness records.csv", "a") as thicknessdb:
thicknessdbWriter = csv.writer(thicknessdb, dialect='excel', lineterminator='\r')
thicknessdbWriter.writerow([get_tool_no] + [todays_date] + [virtual_reading.get()])
thicknessdb.close()
except:
messagebox.showerror("Try Again","Please Enter A Number")
tool_no_entry.delete(0, END)
def cbf(g, l, t):
global g_level, g_reading, g_bits
if g == DATA:
if l == 0:
g_level = 1
else:
g_level = 0
elif g == CLOCK:
if l == pigpio.TIMEOUT:
if g_bits > 10:
show(g_bits, g_reading)
g_reading=0
g_bits=0
elif l == 0:
g_reading = g_reading | (g_level<<g_bits)
g_bits += 1
go()
record_button = Button(root,width = 30,
height = 8,
text='Measure',
fg='black',
bg="light grey", command = measure)
tool_no_entry = Entry(root)
reading_display = Label(root, font=("Helvetica", 22), text = virtual_reading.get())
reading_display.place(x = 50, y =80)
root.resizable(width=FALSE, height=FALSE)
root.geometry('%dx%d' % (winx,winy))
root.title("Micrometer Reader V1.0")
record_button.place(x = 340, y = 100, anchor = CENTER)
tool_no_entry.place(x = 120, y = 250, anchor=CENTER)
tool_no_entry.focus_set()
root.bind("<Return>", measure)
root.mainloop()
cb2.cancel()
cb1.cancel()
pi.stop()
答案 0 :(得分:1)
你误解了StringVar
的工作方式。例如,您每秒都会重新创建StringVar
,并且只有原始版本与标签相关联。您创建的那个小部件与任何小部件都没有关联,因此它永远不可见。
第二个问题是您将变量与标签错误地关联起来。你这样做了:
reading_display = Label(..., text = virtual_reading.get())
...当您应该这样做以获得自动更新功能时:
reading_display = Label(..., textvariable = virtual_reading)
话虽如此,您根本不需要使用StringVar
。您可以使用它,但它只是您必须管理的额外对象。您可以随时使用configure
方法直接设置显示的字符串
text = "{} {:.3f} {}".format(sign, reading, units)
reading_display.configure(text=text)
注意:不需要致电update
或update_idletasks