2016-01-15 1 views
-1

У меня есть скрипт python, который я написал для проекта Raspberry Pi, сценарий читает значение с микрометра каждую секунду и сохраняет это значение как TkInter StringVar (http://effbot.org/tkinterbook/variable.htm)Получение Pyphons Tkinter для обновления метки с изменяющейся переменной

Я хочу, чтобы эта строка отображалась в пользовательском интерфейсе как метка и обновлялась в пользовательском интерфейсе при изменении значения.

Я предпочел использовать строковый символ Tkinter вместо стандартной строки, потому что я думал, что Tkinter автоматически обновит пользовательский интерфейс, но он, похоже, не работает. В настоящее время скрипт ничего не отображает для метки и не обновляется, когда показывается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

или это. http://stackoverflow.com/questions/2603169/update-tkinter-label-from-variable – Lafexlos

+4

или или http://stackoverflow.com/questions/1918005/making-python-tkinter-label-widget-update на самом деле, один из этих двух последних также следует задумать. – Lafexlos

+0

Я хочу сказать, что все они рекомендуют использовать .update_idletasks(), которые мне не удалось получить. – Ewan321

ответ

1

Вы не понимаете, как работает StringVar. Во-первых, вы воссоздаете StringVar каждую секунду, и только оригинал привязан к ярлыку. Тот, который вы создаете, не связан с виджетами, поэтому он никогда не будет виден.

Вторая проблема заключается в том, что вы неправильно связываете переменную с меткой. Вы делаете это:

reading_display = Label(..., text = virtual_reading.get()) 

... когда вы должны делать это так, чтобы получить функцию автоматического обновления:

reading_display = Label(..., textvariable = virtual_reading) 

Это, как говорится, вам не нужно использовать a StringVar. You может использовать, но это просто дополнительный объект, которым вам нужно управлять. Вы можете сразу установить отображаемую строку с configure методом в любое время вы хотите

text = "{} {:.3f} {}".format(sign, reading, units) 
reading_display.configure(text=text) 

Примечание: вы не нужно вызвать update или update_idletasks

+0

Спасибо за вашу помощь, это очень ценно. Я попробую это, когда у меня появится шанс. – Ewan321

Смежные вопросы