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.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.