Reputation: 2072
I have written some code for a python timer but when ever I run it I get an error but the thing is I don't know what to do so I came here for help after I searched all over the internet for help but I couldn't find anything that matched my problem.
Here is the Error:
Exception in Tkinter callback
Traceback (most recent call last):
File "C:\Program Files\Python33\lib\tkinter\__init__.py", line 1475, in __call__
return self.func(*args)
File "C:\Users\Public\Documents\Programming\Timer.py", line 27, in start
sec = sec + 1
UnboundLocalError: local variable 'sec' referenced before assignment
This is my code:
# Import Modules
from tkinter import *
import time
# Window Setup
root = Tk()
root.title('Timer')
root.state('zoomed')
# Timer Variables
global sec
time_sec = StringVar()
sec = 0
# Timer Start
def start():
while 1:
time.sleep(1)
sec = sec + 1
time_sec.set(sec)
start()
# Timer Setup
Label(root,
textvariable=time_sec,
fg='green').pack()
Button(root,
fg='blue',
text='Start',
command=start).pack()
# Program Loop
root.mainloop()
Could Anyone please help me?
Thanks In Advance!
Upvotes: 2
Views: 17240
Reputation: 21680
You have to initiate global sec
in start.ie:
......
# Timer Start
def start():
global sec
.....
you can put inside it in a class
. so that you don't have to worry about the scope of variables..
from tkinter import *
import time
class App():
def __init__(self):
self.window = Tk()
self.root = Frame(self.window, height=200,width=200)
self.root.pack()
self.root.pack_propagate(0)
self.window.title('Timer')
self.label = Label(text="")
self.label.pack()
self.sec = 0
self.timerupdate()
self.root.mainloop()
def timerupdate(self):
self.sec = self.sec + 1
self.label.configure(text=self.sec)
self.root.after(1000, self.timerupdate)
app=App()
app.mainloop()
Upvotes: 0
Reputation:
You have to declare sec
to be a global inside of start
. Here is how to fix the error:
# Import Modules
from tkinter import *
import time
# Window Setup
root = Tk()
root.title('Timer')
root.state('zoomed')
# Timer Variables
global sec
time_sec = StringVar()
sec = 0
# Timer Start
def start():
while 1:
time.sleep(1)
### You have to declare sec as a global ###
global sec
sec = sec + 1
time_sec.set(sec)
start()
# Timer Setup
Label(root,
textvariable=time_sec,
fg='green').pack()
Button(root,
fg='blue',
text='Start',
command=start).pack()
# Program Loop
root.mainloop()
However, this still has problems because it freezes the screen due to the while
loop. A better way to build a timer with tkinter is like this:
from tkinter import *
root = Tk()
root.title('Timer')
root.state('zoomed')
sec = 0
def tick():
global sec
sec += 1
time['text'] = sec
# Take advantage of the after method of the Label
time.after(1000, tick)
time = Label(root, fg='green')
time.pack()
Button(root, fg='blue', text='Start', command=tick).pack()
root.mainloop()
Also, some advice for the future: never use time.sleep
or a while
loop like that in a GUI. Take advantage of the GUI's mainloop instead. It will save many headaches of stuff freezing or crashing. Hope this helps!
Upvotes: 6