I dont understand root['bg'] = 'red' where root is a tkinter.Tk object

Peter Otten __peter__ at web.de
Mon Nov 17 15:14:20 CET 2014


ast wrote:

> Hello,
> 
> import tkinter
> root = tkinter.Tk()
> 
> Let's see all attributes of root:
> 
>>>> root.__dict__
> {'master': None, 'children': {}, '_tclCommands': ['tkerror', 'exit',
> {'13825848destroy'], 'tk':
> <tkapp object at 0x02949C28>, '_tkloaded': 1}
> 
> Now we change the background color using following command:
>>>> root['bg'] = 'red'
> 
> I am wondering what 'bg' is for object root. Is it an attribute ?
> 
>>>> root.__dict__
> {'master': None, 'children': {}, '_tclCommands': ['tkerror', 'exit',
> {'13825848destroy'], 'tk':
> <tkapp object at 0x02949C28>, '_tkloaded': 1}
> 
> No, 'bg' is not in root attribute's list. So what is it ?

Let's drill down a bit:


>>> import tkinter, inspect
>>> print(inspect.getsource(tkinter.Tk.__setitem__))
    def __setitem__(self, key, value):
        self.configure({key: value})

>>> print(inspect.getsource(tkinter.Tk.configure))           
    def configure(self, cnf=None, **kw):
        """Configure resources of a widget.

        The values for resources are specified as keyword
        arguments. To get an overview about
        the allowed keyword arguments call the method keys.
        """
        return self._configure('configure', cnf, kw)

>>> print(inspect.getsource(tkinter.Tk._configure))
    def _configure(self, cmd, cnf, kw):
        """Internal function."""
        if kw:
            cnf = _cnfmerge((cnf, kw))
        elif cnf:
            cnf = _cnfmerge(cnf)
        if cnf is None:
            return self._getconfigure(_flatten((self._w, cmd)))
        if isinstance(cnf, str):
            return self._getconfigure1(_flatten((self._w, cmd, '-'+cnf)))
        self.tk.call(_flatten((self._w, cmd)) + self._options(cnf))

>>> print(inspect.getsource(root.tk.call))
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/lib/python3.4/inspect.py", line 830, in getsource
    lines, lnum = getsourcelines(object)
  File "/usr/lib/python3.4/inspect.py", line 819, in getsourcelines
    lines, lnum = findsource(object)
  File "/usr/lib/python3.4/inspect.py", line 655, in findsource
    file = getfile(object)
  File "/usr/lib/python3.4/inspect.py", line 536, in getfile
    'function, traceback, frame, or code object'.format(object))
TypeError: <built-in method call of tkapp object at 0x7f84ec9f3370> is not a 
module, class, method, function, traceback, frame, or code object

OK, we've reached C code, from here more traditional methods of code 
inspection are required.

tkinter is a wrapper for a GUI written in tcl/tk. For every GUI element in 
tkinter there is a corresponding tcl object that holds the actual bg data. 
It's just that at some point in the development of tkinter someone thought 
that

widget["bg"] = "red"

is more convenient than

widget.configure(bg="red")

While it would have been possible to choose

widget.bg = "red"

that would have mixed the tcl and python namespaces. When the tcl object 
acquires new attributes hilarity ensues...

(I probably would have chosen widget.gui.bg = "red")




More information about the Python-list mailing list