3

I am learning to create simple GUIs with python using Tkinter. I am currently using the python documentation as reference (link).

First thing I am trying to do is understand the sample code there. I am looking at this piece of code in particular, which creates a dialog box with two buttons, one to print something on the console and other to close the program:

from Tkinter import *

class Application(Frame):
    def say_hi(self):
        print "hi there, everyone!"

    def createWidgets(self):
        self.QUIT = Button(self)
        self.QUIT["text"] = "QUIT"
        self.QUIT["fg"]   = "red"
        self.QUIT["command"] =  self.quit

        self.QUIT.pack({"side": "left"})

        self.hi_there = Button(self)
        self.hi_there["text"] = "Hello",
        self.hi_there["command"] = self.say_hi

        self.hi_there.pack({"side": "left"})

    def __init__(self, master=None):
        Frame.__init__(self, master)
        self.pack()
        self.createWidgets()

root = Tk()
app = Application(master=root)
app.mainloop()
root.destroy()

I understand that the function createWidgets places all the elements in the screen (which is somehow created with the def init statement), but I don't understand why the main screen is created using that init name. I thought this was a convention, but when I changed 'init' for 'main' the buttons were not placed in the screen, so I don't know if the main screen must always be created using that name or it was I who did something wrong there.

I also don't understand why every function is created using (self) (What does that mean?) or why .mainloop is called at the end (I suppose to start the whole program) when I'm not seeing any kind of main loop defined anywhere in the sample code.

I have a basic understanding of how objects work but I am finding python a bit confusing when dealing with things like these. I have looked at the python documentation on this but it seems a bit vague to me.

Any sort of link to more specific documentation (Something less vague than the python one I'm using) will be greatly appreciated.

1stthomas
  • 731
  • 2
  • 15
  • 22
  • You may find this helpful: http://stackoverflow.com/questions/625083/python-init-and-self-what-do-they-do –  Dec 07 '13 at 18:07

4 Answers4

3

Your issue appears to be with classes.

Basically, the __init__ method of a class is called as soon as an instance of that class is created.

An example of the instance being created in your code is :

app = Application(master=root)

this means that your class must be called 'Application' though you haven't included that part.

app is now an 'instance' of the Application class. It is a class object through which you access the class methods(functions inside a class) and it's class attributes(variables inside a class).

the name __init__ is not a convention, and calling it something else will mean it no longer serve the same function. Remember, it is executed when you create an instance (or instantiate) the class.(app = Application()) and not by calling it specifically like any other method. It 'initializes' the class, set's it up with whatever code you specify, so it's ready to go almost before you've even used it.

self took me a little while to grasp. The word self, is actually a convention, technically you could use any word there, but you should never do that, or you will be scolded by the nearest programmer. The word does however, have to be there, and it should be 'self'. Why? What does it do? Well...

When you instantiate(create an instance of) the class, as described above, and you want to use the classes methods etc, you need a way for any particular instance to differentiate itself from any other instance, it's just a way of referencing itself(thus the word self). So class attributes are given the 'self.' prefix and class methods are give 'self' as a first argument as a rule. My understanding is that though you only actually have one Application class written, each time you create a new instance, app1, app2, app3, whatever, they all have kind of pointers that reference them specifically, provided by self, so when you're using one of them and accessing methods etc. your actual class knows which one you are dealing with.

If I was using your instance of Application, app, and wanted to use an attribute(variable) of that class, I would just say app.attribute and to access a method, app.method. I don't have to use self at all in that context. However, to call a method, or reference an attribute inside the code of the class itself, it is self.attribute and self.method(args)(notice the self is prefixed, not an arg when you are actually calling the method from within the class.)

I am sorry if this isn't very clear. These are tricky things to explain, and I am learning myself also. Hope this is of some help.

Totem
  • 7,189
  • 5
  • 39
  • 66
0

The self is because the code is inside the "class" form, so when you use that you're in the territory of the "objects style", so they always use the attributes with self, for more information check this link of Python Object Oriented

If I'm not wrong the _init_ also has to do something with the use of objects, so there is the necesity of using this _init_ in order to get things work.

And about the mainloop , this is a function called mainloop() which you will import from Tkinter, which is done at the begining, without this nothing will be displayed the way it should be, and if you work or try using pygame you will see that they also use this mainloop thing in a similar way, it supposedly keep updating the screen display at certain numbers of frames per second, I suppose.

And by the way, you will find different ways in which Tkinter is used to do the same thing, at least I've seen 3 ways: one is like your example, a very organized style; the second is one in which all the code is in a logic order but seems to be a little bit clumsy; the third one is similar to your example code but with another twist. So you must try to experiment with different styles so will learn different tricks.

jenko_cp
  • 103
  • 1
  • 8
0

when you create an object from a class, you 'instantiate' the class. When you do this, the __init__ method will execute. Think of __init__ as 'initialize'.

when you wrote

app = Application(master=Tk())

you are instantiating the Application class by creating a class object called app.

By passing Tk() in, your class inherits the methods from the Tk class, which gives your class the same functionality of the Tk() class (buttons, labels, check boxes, etc.).

self IS the class object, which in your case is app. It may seem redundant or unnecessary to always pass a reference to the object in each class method, but python requires this so get used to always using self.

mark jay
  • 1,256
  • 14
  • 23
0

I think part of the confusion might be here:

from Tkinter import *

class Application(Frame):

This class is inheriting from Frame which comes from Tkinter meaning that after you call

app = Application(master=root)

app is now a subclassed version of Tkinter.Frame.

For me, I would write

import Tkinter as tk 

so then it would be more clear which code/objects are coming from Tkinter vs. what is coming from you.

kztd
  • 3,121
  • 1
  • 20
  • 18