1

I'm currently learning Tkinter and I was wondering whether doing the following is a bad habit for widgets that I'm not using other than putting them on the screen.

Label(root, text="Hello World!").grid(row=0, column=0)

Or would it be better to use two lines like this and create a variable:

myLabel = Label(root, text="Hello World!")
myLabel.grid(row=0, column=0)
Max
  • 37
  • 5
  • 2
    If you are not going to use a particular widget then you can. But generally it's Better to split them up –  Aug 05 '21 at 16:28
  • It depends on what you are trying to accomplish. Doing it inline might prevent your ability to implement certain parameters. At least, that's been my experience. I typically use the second format (two lines). – Dan Curry Aug 05 '21 at 16:29
  • 1
    From Python 3.8+, you can also use `(myLabel := Label(root, text="Hello World!")).grid(row=0, column=0)`. – acw1668 Aug 05 '21 at 16:31
  • Look at [this](https://stackoverflow.com/questions/1101750/tkinter-attributeerror-nonetype-object-has-no-attribute-attribute-name) issue that a lot of people run into. Also try this in python: `import this`. – TheLizzard Aug 05 '21 at 16:33
  • @TheLizzard That issue comes up if you try to assign to the variable and also use `grid()` or `pack()`. But this question is specifically about the case where you don't assign a variable. – Barmar Aug 05 '21 at 16:37
  • @Barmar Yes but I don't think it's uncommon for people to forget that they need to split it in 2 lines when they want the widget. Given that that question has been viewed >100k times, I think it's safe to say that it's better to split it. – TheLizzard Aug 05 '21 at 16:41
  • 1
    @DanCurry: doing it inline doesn't prevent the ability to use certain parameters. You can use the same parameters whether you split it up or not. – Bryan Oakley Aug 06 '21 at 03:55
  • @acw1668 Thanks, I've been meaning to research that operator! – Max Aug 08 '21 at 00:24

2 Answers2

2

It's not bad per se (assuming you never need to refer to the widgets later) but I personally think it's best to always use variables. In my experience, the layout of a group of widgets will change more than the creation of the widget itself as the app evolves. I think it's smart to group widget creation together, and then group layout commands together. It makes the layout much easier to visualize from the code, and makes debugging the layout much easier.

Plus, of course, if you need to access the variables later then you must use a variable.

So, while it doesn't matter at all with a single widget, it can matter a lot when you have multiple widgets. Given that you must use a variable some of the time, I think it's best to be consistent and use variables all of the time.

For example, consider this code:

label1 = tk.Label(root, text="First Name:")
label2 = tk.Label(root, text="Last Name:")
entry1 = tk.Entry(root)
entry2 = tk.Entry(root)

label1.grid(row=0, column=0, sticky="e")
entry1.grid(row=0, column=1, sticky="ew")
label2.grid(row=1, column=0, sticky="e")
entry2.grid(row=1, column=1, sticky="ew")

I personally find the above to be much more readable than either of the following two examples.

Calling grid inline:

tk.Label(root, text="First Name:").grid(row=0, column=0, sticky="e")
tk.Label(root, text="Last Name:").grid(row=1, column=0, sticky="e")
tk.Entry(root).grid(row=0, column=1, sticky="ew")
tk.Entry(root).grid(row=1, column=1, sticky="ew")

Calling grid interleaved with widget creation:

label1 = tk.Label(root, text="First Name:")
label1.grid(row=0, column=0, sticky="e")
label2 = tk.Label(root, text="Last Name:")
label2.grid(row=1, column=0, sticky="e")
entry1 = tk.Entry(root)
entry1.grid(row=0, column=1, sticky="ew")
entry2 = tk.Entry(root)
entry2.grid(row=1, column=1, sticky="ew")        
Bryan Oakley
  • 370,779
  • 53
  • 539
  • 685
1

It depends on your use case, if you plan on reusing the variable in the future, say, update its text, or so on then you will have to store it in a variable. If not, it is all fine to grid() on then at the same line and not store it anywhere, as it really does not matter.

# Not updatable
Label(root, text="Hello World!").grid(row=0, column=0)

# Updatable later
myLabel = Label(root, text="Hello World!")
myLabel.grid(row=1, column=0)

Also remember myLabel = Label(root, text="Hello World!").grid(row=0, column=0) is not updatable as myLabel is None and hence not updatable. So there is no "better" way because if you want to update certain options, you have to store it in a variable and make sure it is not None. If you do not want to update it, then it being None does not matter.

With that said, usually the widgets that require to be stored in a variable are Entry and Text, the rest usually does not require to be stored.

Delrius Euphoria
  • 14,910
  • 3
  • 15
  • 46