[Tutor] Help passing parameters to cancel callback (after_cancel)

Rick Pasotto rick@niof.net
Sun, 1 Apr 2001 10:18:32 -0400


On Sun, Apr 01, 2001 at 03:41:26AM -0400, dkstewaP@netscape.net wrote:
> I am trying to build a demonstration/test module for process control
> application using Tkinter. I want to include a clock updating in one
> second intervals that can be started and stopped by the user
> (effictively a stop watch type application). My previous programming
> experience has been in various flavours of basic including VBA for
> quite complex applications in msWord and Excel. 
> 
> I am very confused as to how I pass the id parameter from the call to
> after() to the after_cancel() function. I think my problems are
> related to the scope of variables (namespaces in python) and how to
> refer to the variable in the various namespaces. The combination of
> using a class to define my functions and having to pass additional
> namespace info to Tkinter has really got me beat.

Your class is a namespace. Each instance of the class is a namespace.
The easiest way to do what you want is to save the return value in
self.return_value.

Following is my version of a program that does what you want (and a
little more). I've interspersed some comments.

Note that you can't pass a parameter to a function specified in a
'command =' parameter. (At least not directly. You can fudge it with
a lambda.) The reason is that 'command =' takes the *name* of a function
not the function itself - thus there are no parens.

#!/usr/bin/evn python

from Tkinter import *
import time
# avoid possible name collisions

class Main:
	def __init__(self,win):
		self.win = win
		self.lbl = Label(self.win,width=40,height=3,bg='lightpink')
		self.lbl.pack(padx=5,pady=5)
		frm = Frame(self.win)
		self.start = Button(frm,text='Start',command=self.do_start)
		self.start.pack(side=LEFT,padx=15,pady=5)
		self.stop = Button(frm,text='Stop',command=self.do_stop)
		self.stop.pack(side=LEFT,padx=15,pady=5)
		frm.pack()
		self.go = 0
# set a global to know whether or not the clock is running

	def do_start(self):
		if not self.go:
			self.go = 1
			self.set_time()
	
	def set_time(self):
		self.lbl.config(text="\n%s" % time.ctime(time.time()))
# time.time() returns the number of seconds since the epoch
# formatting it looks nicer
		self.rtn = self.win.after(1000,self.set_time)
		print self.rtn
# notice that the return value is different every time
	
	def do_stop(self):
		if self.go:
			self.go = 0
			self.win.after_cancel(self.rtn)

if __name__ == '__main__':
	root = Tk()
	main = Main(root)
	root.mainloop()

> My sample code follows (adapted from the hello word example in "An
> Introduction to Tkinter"). Any help to fix the code and to help me
> understand Python would be gratefully appreciated.
> 
> David
> Brisbane, Australia
> 
> # File: hello2.py
> """Display System Time String - potential GUI for stop watch or similar module
> 
>     Stop button should cleanly break out of the polling loop"""
> 
> from Tkinter import *
> from time import *
> 
> class App:
> 
>     def __init__(self, master):
> 
>         self.idn = 0
>         self.master = master
>         frame = Frame(master, width = 512 , height = 256,)
>         frame.pack()
> 
>         self.label = Label(frame, text="The system time is") 
>         self.label.place(relx=0.1, rely=0.2)
> 
>         self.label2 = Label(frame, text=" ", width = 36 , height = 1, relief=RAISED) 
>         self.label2.place(relx=0.5, rely=0.2)
>         
>         self.button = Button(frame, text="STOP", fg="red", command=self.stop(self.idn))
>         self.button.place(relx=0.5, rely=0.8)
> 
>         self.hi_there = Button(frame, text="Quit", command=sys.exit)
>         self.hi_there.place(relx=0.7, rely=0.8)
> 
>         self.idn = self.poll() # start polling
> 
>     def stop(self, idn):
>         self.master.after_cancel(idn)
> 
>     def poll(self):
>         count = time()
>         self.label2.configure(text=str(count))
>         nn  = self.master.after(1000, self.poll)
>         return nn
> 
> root = Tk()
> app = App(root)
> root.mainloop()

-- 
"Prohibition...goes beyond the bounds of reason in that it attempts to
control a man's appetite by legislation and makes a crime out things
that are not crimes. A prohibition law strikes a blow at the very
principles upon which our government was founded."
		-- Abraham Lincoln, Dec. 1840
		   Rick Pasotto email: rickp@telocity.com