1

So, I have been having trouble figuring out what does return do when used for tkinter widgets

here are 3 blocks of code that have the same result, and I wasn't sure what their difference is and whether they differ in performance, and finally, which one is the standard approach

1

import tkinter as tk
class App:
    def __init__(self):
        window = tk.Tk()
        self.label_in_window(window, text = "hello world!")
        window.mainloop()

    def label_in_window(self, parent, text):
        return tk.Label(parent, text = text).pack()
App()

2

import tkinter as tk
class App:
    def __init__(self):
        window = tk.Tk()
        self.label_in_window(window, text = "hello world!")
        window.mainloop()

    def label_in_window(self, parent, text):
        tk.Label(parent, text = text).pack()
        return
App()

3

import tkinter as tk
class App:
    def __init__(self):
        window = tk.Tk()
        self.label_in_window(window, text = "hello world!")
        window.mainloop()

    def label_in_window(self, parent, text):
        tk.Label(parent, text = text).pack()
App()
Ali Keykha
  • 15
  • 3
  • 1
    Does this answer your question? [Tkinter: AttributeError: NoneType object has no attribute ](https://stackoverflow.com/questions/1101750/tkinter-attributeerror-nonetype-object-has-no-attribute-attribute-name) – TheLizzard Aug 23 '21 at 10:27
  • If you want to return the widget, none of the methods above work. You should instead use `label = tk.Label(...); label.pack(); return label` – TheLizzard Aug 23 '21 at 10:28
  • Actually I don't want to return the widget, I just want it to show the widget – Ali Keykha Aug 23 '21 at 10:34
  • Ok then all the examples are identical in functionality. – TheLizzard Aug 23 '21 at 10:36

2 Answers2

3

In the first example you used:

return tk.Label(parent, text=text).pack()

Which creates a label, calls .pack() on the label. It returns whatever .pack() returns (which is None). For more info please read this. So it's identical to:

tk.Label(parent, text=text).pack()
return None

The second example uses:

tk.Label(parent, text = text).pack()
return

Which creates the label. The return is the same as return None.


In the third example uses:

tk.Label(parent, text=text).pack()

Which creates a label then returns None.


Therefore, all the examples that you have shown are exactly the same. They all create a label and return None.

PS: If you use from dis import dis and then dis(App.label_in_window), you will see the decompiled bytecode, which is what python actually uses to run your code.

TheLizzard
  • 7,248
  • 2
  • 11
  • 31
3

Per code answer:

  1. does not make sense, because you are returning something, but then throwing the returned result away.
  2. you can remove the return statement because all functions by default return None, and a return statement without a value also returns None. This then makes 2. and 3. equal.
  3. If you just want to put the creation of widgets into a separate function, use the 3rd code.

Anyways, all the returns do not make sense in your code, because they will always return None. Guess why ? No ? I'll explain it. It's because of this line:

tk.Label(parent, text = text).pack()

First you create a tk.Label object. Then, you call its pack method which of course returns None. So in the end, you have not a tk.Label, but a None. To change this, you should first assign your tk.Label object to a variable, then call the pack method of the variable, then return the variable:

    def label_in_window(self, parent, text):
        label = tk.Label(parent, text=text)
        label.pack()
        return label

But, if you are not planning to use the label later (set a new text, for example), it doesn't make sense to return the label. If you do want to use it later, the standard approach in a class would be to assign the label to an attribute of your class. Also, you should move the window.mainloop out of the class, and functions / methods should be named after what they do, not which result they produce:

import tkinter as tk
class App:
    def __init__(self):
        self.window = tk.Tk()
        self.add_label(self.window, text="hello world!")

    def add_label(self, parent, text):
        self.label = tk.Label(parent, text=text)
        self.label.pack()

app = App()
app.window.mainloop()
TheEagle
  • 5,808
  • 3
  • 11
  • 39