Search code examples
python-3.xclassinheritancetkintersuper

Analysis and understanding of a tkinter code fragment


I'm Brian! I have some experience with Python 2, 3 and tkinter. However, I could never fully understand the way this common tkinter piece of code used by the majority of python programmers which use the tkinter module:

To ensure I have appropiate responses from people, this question is about the following themes: Classes, Inheritance, super() built in function, and "master" parenting in tkinter. They are already included in the tags section.


The Code

I know it's boring, but in order to reply the question I need to give you a clear concept of what I am looking for, implying that this question is about code understanding/reasoning.

We start with this code:

import tkinter as tk

class App(tk.Frame):
    def __init__(self,master):
        super().__init__(master)

        self.lbl = Label(master,text="This is a label sample.")
        self.lbl.pack()

root = tk.Tk()
program = App(root)
program.mainloop()

And our objective is to understand what's the importance/role in overriding the parent's class init() method with the indicated "master", if all of our internal widgets will won't exactly have the parent's class class as their master, instead the tkinter Tk() object. (You will understand better the proposal with the analysis).

Analysis

The code starts with the statement import tkinter as tk. Then we can use the tk namespace as a reference to the tkinter module.

IMAGE001

The next line declares a new class called "App", which becomes child of and inherits the "tk.Frame" methods.

IMAGE002

Taking as a reference the code (for easier understanding):

root = tk.Tk()
program = App(root)

Now we can refer to the parameters with an actual valid name

tk.Tk() gets passed as a parameter on App()'s __init__() method: So we add it in the graphic.

IMAGE003

As the App() instance gets created, self references to the instance program, and master references root which is tk.Tk().

The next line is super().__init__(master) which overrides tk.Frame __init__() method, inserting the master parameter with App's master value. Therefore we can traduce this as tk.Frame.__init__(tk.Tk())

IMAGE004

Then a tk.Label() widget gets created with Label(master,text="This is a label sample."), putting App()'s master parameter as the Label()'s widget master.

IMAGE005

After that, the tk.Label() widget gets packed (which is insignificant for the question).

The Concept and the Question

IMAGE005

Now, according to some programmers, the App(tk.Frame) and super().__init__(master) lines are to create a Frame widget where all elements stated in App() will take place.

But the matter is that...

Why do we have to setup that environment, if as you see in the following graphic, the tk.Label()'s master is tk.Tk() NOT tk.Frame? Is there some concept misunderstanding by me and those two statements have an actual importance in the code?

Thanks in advance.


Solution

  • And our objective is to understand what's the importance/role in overriding the parent's class init() method with the indicated "master", if all of our internal widgets will won't exactly have the parent's class class as their master, instead the tkinter Tk() object.

    If the internal widgets do not have self or one of its descendants as its master, you should not be inheriting from tk.Frame. There is simply no reason to inherit from any of the tk classes if all of the objects in that class are placed in the root window.

    In other words, you should either

    • inherit from tk.Frame and make all widgets created in __init__ be a child of self or one of it's descendants, or
    • do not inherit from tk.Frame, and place all of the widgets wherever you want.

    Mixing those two techniques together makes no sense, and shouldn't be done.