[Tutor] tkinter create a frame and whats the parent

Peter Otten __peter__ at web.de
Wed Sep 23 15:03:23 CEST 2015


David Niklas wrote:

> Hello, I was following the doc, and in the beginning he gives an
> example where he creates a frame and accesses the main window by the
> name of Master.
> 
> http://infohost.nmt.edu/tcc/help/pubs/tkinter/tkinter.pdf

I suppose you are asking about

"""
#!/usr/bin/env python      
import Tkinter as tk       

class Application(tk.Frame):              
    def __init__(self, master=None):
        tk.Frame.__init__(self, master)   
        self.grid()                       
        self.createWidgets()

    def createWidgets(self):
        self.quitButton = tk.Button(self, text='Quit',
            command=self.quit)            
        self.quitButton.grid()            

app = Application()                       
app.master.title('Sample application')    
app.mainloop()                            
"""

A link that is more accessible than the PDF is

http://infohost.nmt.edu/tcc/help/pubs/tkinter/web/minimal-app.html

> I wanted to know, does the name have to be Master? 

You can answer that question yourself. Rename to something unlikely to 
produce a nameclash, e. g. david_niklas, and then run the script again. Does 
it fail? If so, where? Come back here if you have trouble explaining your 
findings.

> And why does he pass
> a second arg to tk.Frame.__init___ ?

Python has "bound" and "unbound" methods. Given a simple example class Foo 
and an instance foo

>>> class Foo:
...     def bar(self, x):
...             return x * x
... 
>>> foo = Foo()

you get an unbound method with

>>> Foo.bar
<unbound method Foo.bar>

and a bound method with

>>> foo.bar
<bound method Foo.bar of <__main__.Foo instance at 0x7fd8855834d0>>

A bound method stores the first argument (usually named self) so that you 
can omit it when you invoke the method. You normally only use bound methods 
as they are easier to invoke. Compare:

>>> foo.bar(2)
4
>>> Foo.bar(foo, 2)
4

Bound methods also make code more generic.

def add_bar_unbound(a, b, x):
    return Foo.bar(a, x) + Foo.bar(b, x)

will always invoke Foo.bar, no matter what kind of object you provide as a 
and b whereas

def add_bar_bound(a, b, x):
    return a.bar(x) + b.bar(x)

will work with with any object that provides a suitable bar method.

But sometimes you have to explicit. How would you write a subclass of Foo 
with a bar method that should do the same calculation as that of Foo.bar and 
then add something?

def bar(self, x):
    return self.bar(x) + 42


doesn't work because it will invoke the same bar() method over and over 
again until it fails. One answer is to use an unbound method:


>>> class Baz(Foo):
...     def bar(self, x):
...             return Foo.bar(self, x) + 42
... 
>>> baz = Baz()
>>> baz.bar(2)
46

Baz.bar invokes Foo.bar which calculates and returns the product of x, then 
Baz.bar adds 42 and returns the result.

You might like to experiment a little and invoke add_bar_bound and 
add_bar_unbound with Foo or Baz instances or any combination. Try to predict 
the results.

(Just in case you want to investigate further: the alternative to unbound 
methods in the context of inheritance is super())





More information about the Tutor mailing list