0

I wanted to create a tkinter function where you have some variables dependent upon time. I wanted it so that every so often the people variable will update with every increment of time. For this example I wanted to make it so that it mimicked customers coming into a store every 5 seconds. Thing is when I click on the menu for customers it doesn't update. How do I get it to update? The time.clock() function updates.

import time from Tkinter import * import tkMessageBox mGui = Tk() mGui.title("Experiment") mGui.geometry('450x450+500+300') def customers(): tkMessageBox.showinfo(title="Customers", message=people) def timer(): tkMessageBox.showinfo(title="Customers", message=time.clock()) people = time.clock()/5 label1 = Label(mGui, text = "label 1").pack() ##Menu menubar = Menu(mGui) filemenu = Menu(menubar, tearoff = 0) menubar.add_cascade(label="In Line", menu=filemenu) filemenu.add_command(label="Customers", command = customers) filemenu.add_command(label="Time", command = timer) mGui.config(menu=menubar) mGui.mainloop() 
3
  • You're diving into the deep end here! To make this work you'll have to glean some knowledge of threading and messaging, as well as delta time. It's not impossible, but it is BROAD. Commented Jul 15, 2014 at 4:33
  • No time.clock(), no time.sleep() only tkinter.after(millisecond, function name) Commented Jul 15, 2014 at 4:53
  • @furas I wouldn't trust tkinter.after to run every millisecond interval. Better to run some sort of timedelta function every short period of time and rely on that instead. Even if you're calling after(5000, foo) and your foo is running every 5,005ms, you're quickly running behind. Commented Jul 15, 2014 at 5:17

1 Answer 1

2

Essentially because you're only calling it once. Your variable people is set to be time.clock() exactly one time -- it does not update the way you think it should, so when you call customers it displays the same old value as always.

A quick fix could be:

def customers(): people = time.clock()//5 # // is integer division. Equivalent to math.floor(x/y) tkMessageBox.showinfo(title="Customers", message=people) def timer(): tkMessageBox.showinfo(title="Timer", message=time.clock() 

That said, this is probably not the BEST way to implement it, since you have to click a button to see each update. How about setting them to StringVars instead?

mGui = Tk() # set geometry as needed people = StringVar(master=mGui, value='') timer = StringVar(master=mGui, value=time.clock()) def update_customers(): global mGui people.set(time.clock()//5) mGui.after(1000, update_customers) # this sets the function to run again after ~1s and re-evaluate def update_timer(): global mGui timer.set(5 - (time.clock() % 5)) mGui.after(1000, update_timer) # this sets the function to run again after ~1s and re-evaluate def start(): global mGui, people, timer update_customers() update_timer() Label(mGui, text="Customers:").pack() Label(mGui, textvariable=people).pack() Label(mGui, text="Time 'till Next Customer:").pack() Label(mGui, textvariable=timer).pack() mGui.mainloop() start() 
Sign up to request clarification or add additional context in comments.

1 Comment

That looks like a great way to go about it. Thanks for the feedback Adam! It is really helpful.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.