让Pyphons Tkinter使用变化的变量更新标签

时间:2016-01-15 11:59:16

标签: python user-interface tkinter raspberry-pi

我有一个我为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()

1 个答案:

答案 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)

注意:需要致电updateupdate_idletasks