Tkinter programming problem

Eric Brunel eric.brunel at pragmadev.com
Fri Aug 1 06:01:32 EDT 2003


Andrew Gregory wrote:
> Could someone help me out with these few lines of code: I would like
> to know why the Quit button in this application removes the buttons
> and causes "Quitting" to be printed, but does not close the outer
> frame.
> 
> Andrew.
> 
> 
> # Demonstration TK interface Windows application
> # Runs ok from within IDLE
> #
> from Tkinter import *
> 
> class CommonStuff:   # to get common access to variables and functions
>     def __init__(cself, frame):
>         cself.frame = frame

It is a Bad Idea to give the first parameter of a method any other name than 
"self"... Checking tools like PyChecker will complain if you do that, and your 
programs will be harder to read for anyone else doing Python...

>     def say_hi(cself):
>         print "Hello all"
> 
> 
> class MyWidgets(Frame, CommonStuff):
>     def __init__(wself, CS):
>         Frame.__init__(wself, CS.frame)

Where have you found this type of Tkinter object initialization? Apparently, 
there are weird style guides lying around somewhere... You can rewrite all of this:

>         wself.quitbutton = Button(wself)
>         wself.quitbutton["text"] = "Quit"
>         wself.quitbutton["fg"]   = "red"
>         wself.quitbutton["command"] = wself.destroy
> 
>         wself.quitbutton.pack({"side": "left"})

like that:

wself.quitbutton = Button(wself, text='Quit', fg='red', command=wself.destroy)
wself.quitbutton.pack(side=LEFT)

This is the most common way to do things. BTW, since you never do anything to 
the buttons themselves ouside this method, there's no need at all to store them 
in attributes. So you can just do:

quitbutton = Button(wself, text='Quit', fg='red', command=wself.destroy)
quitbutton.pack(side=LEFT)

or even:

Button(wself, text='Quit', fg='red', command=wself.destroy).pack(side=LEFT)

>         wself.hi_there = Button(wself)
>         wself.hi_there["text"] = "Hello",
>         wself.hi_there["command"] = CS.say_hi
> 
>         wself.hi_there.pack({"side": "left"})

Same here:

wself.hi_there = Button(wself, text="Hello", command=CS.say_hi)
wself.hi_there.pack(side=LEFT)

or:

hi_there = Button(wself, text="Hello", command=CS.say_hi)
hi_there.pack(side=LEFT)

or even:

Button(wself, text="Hello", command=CS.say_hi).pack(side=LEFT)

> 
> class Application:
>     def __init__(self, master):
>         self.frame=Frame(master)
>         CS = CommonStuff(self.frame)
> 
>         displayedwidget=MyWidgets(CS)
>         displayedwidget.grid(row=0, column=0)
>         self.frame.grid(row=0, column=0)
>         self.frame.columnconfigure(0)

This statement is a no-op: you say you'll configure the column n#0 of 
self.frame, but you do not give any features for the column. What are you trying 
to do?

>         displayedwidget.bind("<Destroy>", self.quit)
>         self.frame.update()
>         
>     def quit(self, event):
>         print"Quitting..."
>         self.frame.destroy  # Destroy frame and all children

Compare this line to the last in the __init__ method just above. To call the 
update method on self.frame, you did self.frame.update(). So to call the destroy 
method on self.frame, you must do self.frame.destroy(). self.frame.destroy 
merely returns the destroy method of the self.frame object, but doesn't do 
anything with it.

> root = Tk()
> mainWin = Application(root)
> root.wait_window(mainWin.frame)

I don't know if this works, but I know it's not the usual way to run a Tkinter 
application. You'd better replace the last line by:

root.mainloop()

HTH

-- 
- Eric Brunel <eric.brunel at pragmadev.com> -
PragmaDev : Real Time Software Development Tools - http://www.pragmadev.com





More information about the Python-list mailing list