Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Python/Tkinter: fine points about super init and self

Following is very simple code to create a frame and label as a class:

class FrameWithLabel(tk.Frame):
    def __init__(self, parent):
        super().__init__(self, parent)
        self.label = tk.Label(self)

I have two questions:

  1. In an earlier post, it was explained to me why the super init was required (in this case, referring to the tk.Frame), and that without the super init, the Frame widget would not be correctly initialized. If that’s the case, then why can the Label simply be passed in as self.label without a similar super init type initialization of a tk Label? There is obviously something I am still not grasping about super init.

    MEDevel.com: Open-source for Healthcare and Education

    Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

    Visit Medevel

  2. This is a very minor point, but I don’t like the way that referring to the Frame and Label are asymmetrical. That is, if I wanted to change an attribute of the frame from the main app, I would use FrameWithLabel.configure(bg="red"). But if I wanted to change the label, I would have to use FrameWithLabel.label.configure(bg="red"). I would rather that the Frame and Label occupied the same level in the code so that I would be referring to FrameWithLabel.frame and FrameWithLabel.label. In that case, the class would have to be initialized with something other than the Frame widget. If that’s possible, what would that element be? I have tried "class SomeClassName(tk):" and it doesn’t work. Also, if there is an element that could be used in this way, would a super init line be required?

My apologies if question 2 seems trivial, since the above code works just fine, but I’m really trying to drill down to how all of this stuff works under the hood, and make my classes as intuitive and user-friendly as possible. Any advice appreciated.

>Solution :

why can the Label simply be passed in as self.label without a similar super init type initialization of a tk Label?

It is because you aren’t subclassing the Label class. The label you create in __init__ is just a normal label. You only need to call super when you’re creating a subclass of a widget.

if I wanted to change the label, I would have to use FrameWithLabel.label.configure(bg="red"). I would rather that the Frame and Label occupied the same level in the code so that I would be referring to FrameWithLabel.frame and FrameWithLabel.label.

This question is unclear. You do refer to the label with FrameWithLabel.label. It’s not clear what you want instead.

If you want to be able to do something like frame_with_label.configure(label="the label") then you’ll have to create a custom configure method. It might look something like this:

class FrameWithLabel(tk.Frame):
    def __init__(self, parent):
        super().__init__(parent)
        self.label = tk.Label(self)
        self.label.pack(padx=10, pady=10)

    def configure(self, **kwargs):
        if "label" in kwargs:
            value = kwargs.pop("label")
            self.label.configure(text=value)

        # call the built-in configure method for the other arguments
        super().configure(**kwargs)

With the above, you can set the label like this:

labelframe = FrameWithLabel(root)
labelframe.configure(label="Hello, world")
Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading