4

I am currently studying a text to try and teach myself more about TkInter as I'm trying to improve my Python 3 programming. The text can be found here, if necessary: http://www.ferg.org/thinking_in_tkinter/all_programs.html

In the section labelled "tt040.py" there is an example code, part of it is:

    self.button1 = Button(self.myContainer1)
    self.button1["text"] = "Hello, World!"   ### (1)
    self.button1["background"] = "green"     ### (1)
    self.button1.pack()


    self.button2 = Button(self.myContainer1)
    self.button2.configure(text="Off to join the circus!") ### (2)
    self.button2.configure(background="tan")               ### (2)
    self.button2.pack()


    self.button3 = Button(self.myContainer1)
    self.button3.configure(text="Join me?", background="cyan")  ### (3)
    self.button3.pack()

The explanation for this part of the code is :

"(2) For button2, the process is essentially the same as for button1, but instead of accessing the button's dictionary, we use the button's built-in "configure" method.

(3) For button3, we see that the configure method can take multiple keyword arguments, so we can set multiple options in a single statement."

What does the explanation actually mean? As in, what is the actual difference (with .pack) or need for the .configure method? What is meant by "the button's dictionary"?

Kage93
  • 411
  • 2
  • 6
  • 6

2 Answers2

4

Tkinter objects attribute are not handled through python attribute mechanism (ie you can not do self.button1.text = "hello"). Instead, tkinter provide two ways to alter this attribute:

  • use the object as a dictionnary: self.button1["text"] = "hello"
  • use the config method with named argument: self.button1.config(text="hello")

Both are equivalent. Note that you could also have passd such initialisation value through constructor named argument to perform both instanciation an initialisation in one step: self.button1 = Button(self.myContainer1, text="hello")

pack serve a totally different purpose. It is a geometry management instruction. Used without argument button1.pack() ask to place button1 in its parent widget below the precedent sibling (if any). You can use options to specify relative position, or resize behavior.

There are other geometry manager for tkinter: grid and place, see this response for a comparison.

Community
  • 1
  • 1
FabienAndre
  • 4,514
  • 25
  • 38
  • Do you happen to know the reasons the attribute mechanism was not chosen? Did the `__setattr__` method and friends simply not exist when Tkinter was first added way back in Python 1.x? Or was it a conscious decision that using `__setitem__` would somehow be better? I'm currently looking to see if there's an old PEP or mailing list where this was discussed but I haven't found anything. – ArtOfWarfare May 10 '15 at 17:12
2

Each widget has a dictionary of attributes (text, background, ...). You can access it using the regular dictionary syntax, as in self.button1["text"] = "Hello, World!" or using the configure method that you see in the other examples. That's just to set up the looks and behaviour of the widget.

Once you're done, you call pack to let Tkinter now that the widget is ready to be used. Then it will be displayed, etc.

You can see this by executing Tkinter commands step by step in the interpreter, like this:

>>> from Tkinter import *
>>> root = Tk()
>>> bt = Button(root)
>>> bt['text'] = 'hello'
>>> bt.pack()
Ricardo Cárdenes
  • 9,004
  • 1
  • 21
  • 34