1

Hi I have a little question about Label in tkinter.

When you use Label outside classes, you do something like

import tkinter as tk


root = tk.Tk()
label = tk.Label(root, text = "something", background = "something")
label.pack()

However, when it's inside a class and the code goes something like

import tkinter as tk

class Example(tk.Frame):

    COLOURS = [ "#f45", "#ee5", "#aa4", "#a1e433", "#e34412", "#116611",
                "#111 eeefff", "#3aa922191", "#abbabbaaa" ]

    def __init__(self, parent):
        tk.Frame.__init__(self, parent)

        self.parent = parent


        col = 1
        for colour in Example.COLOURS:
        #
        label = tk.Label(self, text=colour, background=colour)
        #
        label.grid(row=1, column=col)
        col += 1


def main():
root = tk.Tk()
ex = Example(root)
root.geometry("+300+300")
root.mainloop()

if __name__ == '__main__':
    main()

but shouldn't it be rather like

label = tk.Label(self.parent, text=colour, background=colour)

since self.parent would correspond to root? When I try to do that, I get an error and I only do when I have the label.grid(...) line under it(I tried pack and it worked fine).

So I thought this code

import tkinter as tk

root = tk.Tk()

label = tk.Label(root)
label.grid(row=0, column=0)

root.mainloop()

wouldn't work either, but it actually worked fine. So I'm confused. Can anyone explain?

1 Answer 1

1

No, it should not be self.parent.

In the class example you give, the class is itself a frame. It is designed this way to make the example self-contained. By inheriting from Frame you can take all of the code in that class and put it anywhere in the GUI. You can think of the class and everything in it as a single custom widget. You could have multiple of these classes, and each one can be treated as a single GUI object.

To make that work, the class only ever puts widgets inside itself, not in its parent.

The entire purpose of using a sublcass of Frame is to act as a container for other widgets. If you don't plan on using it as a container for other widgets, there's no point in inheriting from Frame.

It is the equivalent of this, without classes:

import tkinter as tk

root = tk.Tk()
frame = tk.Frame(root)
frame.pack(...)
label = tk.Label(frame, text = "something", background = "something")
label.pack(...)

If you wanted the class to put widgets in the parent, you would define the class like the following. Notice that it inherits from object rather than Frame:

class Example(object):
    def __init__(self, parent):
        self.parent = parent
        ...
        label = tk.Label(parent, ...)
7
  • Oh, so the class I made is automatically a frame because I inherited from the tk.Frame class? Or did initialising the Frame class inside ex.__init__ actually return a frame object?
    – user5972209
    Commented Mar 11, 2016 at 2:06
  • Also, I actually forgot to mention that in the example, root(tk.Tk())is passed to the parent parameter(you probably knew it though).
    – user5972209
    Commented Mar 11, 2016 at 2:08
  • Yes, it is a frame because you inherit from Frame. Commented Mar 11, 2016 at 2:15
  • And you are saying Label's first argument should be a frame not root(tk.Tk())?
    – user5972209
    Commented Mar 11, 2016 at 12:55
  • @NamanJain: the first argument to Label can be anything you want. If you use the class method in the example you should use self, otherwise it's pointless to use the class. the entire purpose of inheriting from Frame in that example is specifically to act as a container for the other widgets. Commented Mar 11, 2016 at 13:15

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.