Tkinter grid layout

Eric Brunel eric_brunel at despammed.com
Thu Jul 7 03:38:32 EDT 2005


On Wed, 06 Jul 2005 16:32:42 GMT, William Gill <noreply at gcgroup.net> wrote:

> Excuse me for intruding, but I followed examples and ended up with a
> similar architecture:
>
>      from Tkinter import *
>      class MyMain(Frame):
>          def __init__(self, master):
>              self.root = master
>              self.master=master
>      root = Tk()
>      app = MyMain(root)
>      app.master.title("Object Editor")
>      root.mainloop()
>
> Erick, are you saying it should be modified to something like :
>
>      from Tkinter import *
>      class MyMain(Tk):
>      ...
>      ...
>      app = MyMain()
>      app.title("My App")
>      app.mainloop()

Well, basically, that's what I'm saying; but your example is a bit better than the OP's.

Basically, the problem is that an instance of MyMain will just be some kind of graphical component that can be inserted into basically anything. So nothing prevents me to do for example:

root = Tk()
Label(root, text='This is my application').pack(side=TOP)
frm = Frame(root)
frm.pack(side=TOP)
app = MyMain(frm)
# You don't show where you pack or grid your MayMain instance in its
# parent, so I'm doing it explicitely here...
app.pack()
root.mainloop()

So the container for MyMain is a Tk instance in your example, and a Frame instance in mine. And it works, because it's basically the use case for Frame sub-classes: they can be pack'ed or grid'ed or place'd into anything.

So MyMain cannot make any assumption on its container (self.master in your first example), since it can be any valid container. So there are many things that you just can't do in MyMain, because you don't have a window. For example, you can't set the window title, or define a menu bar, since all these are defined via methods only available on windows, i.e. Tk or Toplevel instances.

Basically, you did this right, since you call app.master.title(...) in the main script, where you know that app.master is a Tk instance. But what can be the reason to do it *outside* MyMain? Isn't it the window itself that knows what title it should have?

So in your second version, you can do:

 from Tkinter import *
class MyMain(Tk):
   Tk.__init__(self)
   self.title("My App")
   ...
...
app = MyMain()
app.mainloop()

And this always works: since an instance of MyMain is an instance of Tk, you do have a window on which to call title. Note that this cannot be safely done in your first version, since self.master may not have a title method (see my example above).

So you should really stick to the following rules:
- If you write a class defining the main window for your application, make it inherit from Tkinter.Tk
- If you write a class defining a "secondary" window for your application, make it inherit from Tkinter.Toplevel
- If you write a class defining a graphical component that can be placed anywhere in a GUI, make it inherit from Tkinter.Frame
This is basically just a matter of good OO programming: you should choose the most accurate super-classes for the classes you define, or someday, you'll run into problems...

HTH
-- 
python -c "print ''.join([chr(154 - ord(c)) for c in 'U(17zX(%,5.zmz5(17;8(%,5.Z65\'*9--56l7+-'])"



More information about the Python-list mailing list