| | |
Tkinter Countdown Timer problems.
Thread Solved |
Hi. I've just registered, but I'm not exactly new to here (i've been lurking as a guest). I'm trying to make a countdown timer based on a class that I created, which accepts hours, minutes, and seconds as parameters and counts them down to zero, will displaying them in a Tkinter window.
Now, I did start on it using Tkinter, but the Tkinter window just never appears (for some reason, I suspect this has something to do with the time.sleep() i use in my aggregate function, because everything else seems fine and when I the aggregate() function call, the window runs normally.
I managed to create a temporary fix using livewires, that instead of using time.sleep(), uses the mainloop() cycles to decide when to decrement a second (mainloop in livewires do a certain amount of cycles per second). The problem with this is that it isn't always accurate. That is, sometimes it goes too fast, and sometimes it goes too slow with the exact same FPS settings (I suspect this has to do with my CPU load or something...i'm not very skilled and I don't know a lot about these things).
Another problem with the livewires method is that while in Tkinter, I could just destroy() the timer window when the timer is through and call back the main window(I want the timer to quit, and open back the start screen when it is through), with this livewires version it just locks up when i tell it screen.quit() (The destroy() function only wipes all the objects off. Heres the code (so sorry for lack of commenting...i was supposed to comment it last night, but got sidetracked and now im at work and dont have much time. I'll add comments if you cant understand the code):
the parameter "passer" in in this format:
("string",(int_hh, int_mm, int_ss))
Now, I did start on it using Tkinter, but the Tkinter window just never appears (for some reason, I suspect this has something to do with the time.sleep() i use in my aggregate function, because everything else seems fine and when I the aggregate() function call, the window runs normally.
I managed to create a temporary fix using livewires, that instead of using time.sleep(), uses the mainloop() cycles to decide when to decrement a second (mainloop in livewires do a certain amount of cycles per second). The problem with this is that it isn't always accurate. That is, sometimes it goes too fast, and sometimes it goes too slow with the exact same FPS settings (I suspect this has to do with my CPU load or something...i'm not very skilled and I don't know a lot about these things).
Another problem with the livewires method is that while in Tkinter, I could just destroy() the timer window when the timer is through and call back the main window(I want the timer to quit, and open back the start screen when it is through), with this livewires version it just locks up when i tell it screen.quit() (The destroy() function only wipes all the objects off. Heres the code (so sorry for lack of commenting...i was supposed to comment it last night, but got sidetracked and now im at work and dont have much time. I'll add comments if you cant understand the code):
#Te-je Rodgers
#Counter module
from livewires import games, color
class Counter(games.Sprite):
"""My counter is a sprite."""
def __init__(self, screen, x, y,image, passer):
self.screen = screen
self.init_sprite(screen = screen, x = x, y = y, image=image)
self.name=passer[0]
timer=passer[1]
self.hh=timer[0]
self.mm=timer[1]
self.ss=timer[2]
self.count=0
self.col=color.blue
games.Text(screen=screen, x=200, y=20, text=self.name, color = color.white, size=50)
games.Text(screen=screen, x=200, y=180, text="Press ENTER or F1 to stop",
color=color.white, size=20)
self.display_message()
def close_timer(self):
if self.hh<0:
import last
else:
self.screen.quit()
def good(self):
x=0
def display_message(self):
games.Message(screen = self.screen, x=200, y=100,
text=str(self.hh)+" : "+str(self.mm)+" : "+str(self.ss), size=100, after_death=self.good(),
color=self.col, lifetime=75)
def decrease_seconds(self):
self.ss-=1
if self.hh>=0:
if self.ss<0:
self.ss=59
self.mm-=1
if self.mm<0:
self.mm=59
self.hh-=1
if self.hh<0:
self.close_timer()
else:
self.display_message()
else:
self.display_message()
else:
self.display_message()
def moved(self):
self.count+=1
if self.screen.is_pressed(games.K_RETURN) or self.screen.is_pressed(games.K_F1) or self.screen.is_pressed(games.K_KP_ENTER):
self.close_timer()
if self.hh==0 and self.mm==0 and self.ss==6:
self.col=color.red
if self.count==75:
self.decrease_seconds()
self.count=0
def start(passer):
root32=games.Screen(400, 200)
sprite_image=games.load_image("img.bmp")
back=games.load_image("box2.jpg")
root32.set_background(back)
x=Counter(root32, 296, 139, sprite_image, passer)
root32.mainloop(50)
the parameter "passer" in in this format:
("string",(int_hh, int_mm, int_ss))
Please use the [code=python] and [/code] tag pair to enclose your python code. Otherwise you lose all your indentations and you code becomes unusable!
With the housekeeping out of the way, "Welcome to the Python forum!"
With the housekeeping out of the way, "Welcome to the Python forum!"
Last edited by vegaseat; Feb 7th, 2007 at 2:28 pm.
May 'the Google' be with you!
humblest apologies.
Livewires based timer:
Tkinter timer(not working at all):
Livewires based timer:
python Syntax (Toggle Plain Text)
#Te-je Rodgers #Counter module from livewires import games, color class Counter(games.Sprite): """My counter is a sprite.""" def __init__(self, screen, x, y,image, passer): self.screen = screen self.init_sprite(screen = screen, x = x, y = y, image=image) self.name=passer[0] timer=passer[1] self.hh=timer[0] self.mm=timer[1] self.ss=timer[2] self.count=0 self.col=color.blue games.Text(screen=screen, x=200, y=20, text=self.name, color = color.white, size=50) games.Text(screen=screen, x=200, y=180, text="Press ENTER or F1 to stop", color=color.white, size=20) self.display_message() def close_timer(self): if self.hh<0: import last else: self.screen.quit() def good(self): x=0 def display_message(self): games.Message(screen = self.screen, x=200, y=100, text=str(self.hh)+" : "+str(self.mm)+" : "+str(self.ss), size=100, after_death=self.good(), color=self.col, lifetime=75) def decrease_seconds(self): self.ss-=1 if self.hh>=0: if self.ss<0: self.ss=59 self.mm-=1 if self.mm<0: self.mm=59 self.hh-=1 if self.hh<0: self.close_timer() else: self.display_message() else: self.display_message() else: self.display_message() def moved(self): self.count+=1 if self.screen.is_pressed(games.K_RETURN) or self.screen.is_pressed(games.K_F1) or self.screen.is_pressed(games.K_KP_ENTER): self.close_timer() if self.hh==0 and self.mm==0 and self.ss==6: self.col=color.red if self.count==75: self.decrease_seconds() self.count=0 def start(passer): root32=games.Screen(400, 200) sprite_image=games.load_image("img.bmp") back=games.load_image("box2.jpg") root32.set_background(back) x=Counter(root32, 296, 139, sprite_image, passer) root32.mainloop(50)
Tkinter timer(not working at all):
python Syntax (Toggle Plain Text)
#Gamal Crichton #Teje's Counter #04/02/07 from Tkinter import * import time class Application(Frame): def __init__(self,master,act_name,time_): Frame.__init__(self,master) self.hh=time_[0] self.mm=time_[1] self.ss=time_[2] self.name=act_name self.grid() print time_ self.disp_widgets() self.aggregate() def disp_widgets(self): #Uses labels to diaply time. Label(self, text=self.name, font=("Arial, 32") ).grid(row=0,column=0,columnspan=3,sticky=W) self.hourlbl=Label(self, text=self.hh, font=("Arial, 40") ) self.hourlbl.grid(row=1,column=0,columnspan=1,sticky=W) self.minutelbl=Label(self, text=self.mm, font=("Arial, 40") ) self.minutelbl.grid(row=1,column=1,columnspan=1,sticky=W) self.secondlbl=Label(self, text=self.ss, font=("Arial, 40") ) self.secondlbl.grid(row=1,column=2,columnspan=1,sticky=W) Button (self, text="Stop", command=self.show, ).grid(row=2,column=0,sticky=E, columnspan=3) def show(self): print "Booooooooo!" def aggregate(self): #This function is supposed to decrement the time for hours in range(self.hh, -1, -1): for minutes in range(self.mm, -1, -1): for seconds in range(self.ss, -1, -1): time.sleep(1) self.secondlbl["text"]=seconds if self.ss==0: self.ss=60 self.minutelbl["text"]=minutes if self.mm==0: self.mm=0 self.hourlbl["text"]=hours #Main root=Tk() root.title("Timer!") root.geometry("250x75") app= Application(root, "Timer", [2, 4, 5]) root.mainloop()
•
•
Join Date: Jul 2006
Posts: 608
Reputation:
Solved Threads: 150
Hey ... I recognize that version of livewires from "Python Programming for the Absolute Beginner", yes?
I've successfully done a timer before and recall that there was a subtle trick to it. I'll try to look it up at school.
In the meantime, I want to register a major complaint with the new formatting for [ code = Python ] and [/ code] tags. The line numbers make it impossible to cut-and-paste code from the posting into IDLE. Unless I'm missing something?
Jeff
I've successfully done a timer before and recall that there was a subtle trick to it. I'll try to look it up at school.
In the meantime, I want to register a major complaint with the new formatting for [ code = Python ] and [/ code] tags. The line numbers make it impossible to cut-and-paste code from the posting into IDLE. Unless I'm missing something?
Jeff
Jeff, yes you are missing something and so did I until Henri Bumsfeld pointed it out ...
http://www.daniweb.com/techtalkforums/post311639-5.html
http://www.daniweb.com/techtalkforums/post311639-5.html
May 'the Google' be with you!
•
•
Join Date: Sep 2005
Posts: 133
Reputation:
Solved Threads: 58
Hi!
Change your aggregate function to:
@jrcagle: Do you see the Toggle Plain Text below the code? Click it and be happy
Regards, mawe
Change your aggregate function to:
Python Syntax (Toggle Plain Text)
def aggregate(self): #This function is supposed to decrement the time for hours in range(self.hh, -1, -1): for minutes in range(self.mm, -1, -1): for seconds in range(self.ss, -1, -1): time.sleep(1) self.update() # <== ...
@jrcagle: Do you see the Toggle Plain Text below the code? Click it and be happy

Regards, mawe
Hey mawe. I take it I need to just write an update method with all the stuff that was there in it?
And yeah Jeff, it was that book. It's the one we use in school....well it's the one the school told us to take and go learn python on our own. It's sitting open on my printer to the livewires reference page right now, incidentally.
Well thanks guys for all your help. I'll try it when I get to work, cause I'm late for school right now. Let you know how it goes.
And yeah Jeff, it was that book. It's the one we use in school....well it's the one the school told us to take and go learn python on our own. It's sitting open on my printer to the livewires reference page right now, incidentally.
Well thanks guys for all your help. I'll try it when I get to work, cause I'm late for school right now. Let you know how it goes.
A couple of things wrong with your countdown timer.
1 - don't limit the size of your root window, widgets won't fit
2 - labels take strings
3 - root.update() is needed
Look this over:
[php]#Gamal Crichton
#Teje's Counter
#04/02/07
from Tkinter import *
import time
class Application(Frame):
def __init__(self,master,act_name,time_):
Frame.__init__(self,master)
self.hh=time_[0]
self.mm=time_[1]
self.ss=time_[2]
self.name=act_name
self.grid()
print time_
self.disp_widgets()
self.aggregate()
def disp_widgets(self):
#Uses labels to display time.
Label(self,
text=self.name, font=("Arial, 32")
).grid(row=0,column=0,columnspan=3,sticky=W)
self.hourlbl=Label(self,
text=str(self.hh), font=("Arial, 40") # str()!!!!!!!!!!
)
self.hourlbl.grid(row=1,column=0,columnspan=1,sticky=W)
self.minutelbl=Label(self,
text=str(self.mm), font=("Arial, 40") # str()!!!!!!!!!!
)
self.minutelbl.grid(row=1,column=1,columnspan=1,sticky=W)
self.secondlbl=Label(self,
text=str(self.ss), font=("Arial, 40") # str()!!!!!!!!!!
)
self.secondlbl.grid(row=1,column=2,columnspan=1,sticky=W)
Button (self,
text="Stop",
command=self.show,
).grid(row=2,column=0,columnspan=3,sticky=EW)
def show(self):
# needs more stuff
print "Booooooooo!"
def aggregate(self): #This function is supposed to decrement the time
for hours in range(self.hh, -1, -1):
for minutes in range(self.mm, -1, -1):
for seconds in range(self.ss, -1, -1):
time.sleep(1)
root.update() # needed!!!!!
self.secondlbl["text"]=str(seconds) # str()!!!!!!!!!!
if self.ss==0:
self.ss=60
self.minutelbl["text"]=str(minutes) # str()!!!!!!!!!!
if self.mm==0:
self.mm=0
self.hourlbl["text"]=str(hours) # str()!!!!!!!!!!
#Main
root=Tk()
root.title("Timer!")
#root.geometry("250x75") # do not use, too space restrictive!!!
app= Application(root, " Timer ", [2, 4, 5])
root.mainloop()
[/php]
1 - don't limit the size of your root window, widgets won't fit
2 - labels take strings
3 - root.update() is needed
Look this over:
[php]#Gamal Crichton
#Teje's Counter
#04/02/07
from Tkinter import *
import time
class Application(Frame):
def __init__(self,master,act_name,time_):
Frame.__init__(self,master)
self.hh=time_[0]
self.mm=time_[1]
self.ss=time_[2]
self.name=act_name
self.grid()
print time_
self.disp_widgets()
self.aggregate()
def disp_widgets(self):
#Uses labels to display time.
Label(self,
text=self.name, font=("Arial, 32")
).grid(row=0,column=0,columnspan=3,sticky=W)
self.hourlbl=Label(self,
text=str(self.hh), font=("Arial, 40") # str()!!!!!!!!!!
)
self.hourlbl.grid(row=1,column=0,columnspan=1,sticky=W)
self.minutelbl=Label(self,
text=str(self.mm), font=("Arial, 40") # str()!!!!!!!!!!
)
self.minutelbl.grid(row=1,column=1,columnspan=1,sticky=W)
self.secondlbl=Label(self,
text=str(self.ss), font=("Arial, 40") # str()!!!!!!!!!!
)
self.secondlbl.grid(row=1,column=2,columnspan=1,sticky=W)
Button (self,
text="Stop",
command=self.show,
).grid(row=2,column=0,columnspan=3,sticky=EW)
def show(self):
# needs more stuff
print "Booooooooo!"
def aggregate(self): #This function is supposed to decrement the time
for hours in range(self.hh, -1, -1):
for minutes in range(self.mm, -1, -1):
for seconds in range(self.ss, -1, -1):
time.sleep(1)
root.update() # needed!!!!!
self.secondlbl["text"]=str(seconds) # str()!!!!!!!!!!
if self.ss==0:
self.ss=60
self.minutelbl["text"]=str(minutes) # str()!!!!!!!!!!
if self.mm==0:
self.mm=0
self.hourlbl["text"]=str(hours) # str()!!!!!!!!!!
#Main
root=Tk()
root.title("Timer!")
#root.geometry("250x75") # do not use, too space restrictive!!!
app= Application(root, " Timer ", [2, 4, 5])
root.mainloop()
[/php]
Last edited by Ene Uran; Feb 8th, 2007 at 12:46 pm. Reason: spelling
drink her pretty
WOOHOO! THanks you guys. I now have a working timer. The problem was that I mis-interpreted mawe's post and wrote my own self.update()....that didn't work. But it was from the last post that I got egged on that Tk objects have update methods, and I used it after and it works just fine now.
Thanks!
python Syntax (Toggle Plain Text)
self.hourlbl["text"]=self.hh #etc....
Thanks!
Last edited by scru; Feb 9th, 2007 at 2:39 pm.
![]() |
Other Threads in the Python Forum
- Previous Thread: Horizontal Buttom Placement
- Next Thread: Tkinter Listbox Preselect
| Thread Tools | Search this Thread |
alarm ansi app assignment avogadro backend beginner binary bluetooth character cipher cmd customdialog cx-freeze data decimals dictionary directory dynamic error exe file float format function generator getvalue gnu graphics halp heads homework http ideas import input ip itunes java keycontrol leftmouse line linux list lists loop maintain maze millimeter module mouse number numbers output parsing path pointer prime programming progressbar push py2exe pygame python queue random recursion schedule screensaverloopinactive script slicenotation sqlite ssh statistics string strings sudokusolver sum text thread threading time tlapse tuple tutorial ubuntu unicode url urllib urllib2 variable variables ventrilo vigenere web webservice wikipedia write wxpython xlib






