Search code examples
pythontkintertkinter-label

Is .grid on the same line different as to on a seperate line


I am getting this below error when i try to run my code (at the bottom).

AttributeError: 'NoneType' object has no attribute 'config'
Exception in Tkinter callback

soo is this. this method works with the config and win10toast

L1 = Label(win, text = "Press a button")
L1.grid(row= 0, column= 0, columnspan= 2, padx = 20, pady = 20)

the same as this. if not what are the differences. as far as i knew they were the same just one is smaller and on one line.

L1 = Label(win, text = "Press a button").grid(row= 0, column= 0, columnspan= 2, padx = 20, pady = 20)

Main code

import datetime as dt
from win10toast import ToastNotifier
from tkinter import *
toast = ToastNotifier()

win = Tk()
win.geometry("200x150")
win.resizable(False, False)
win.configure(background = "Light Blue")
win.title("Demo")
def greeting():
    L1.config(text = "Hello")
    toast.show_toast("Alarm", "You have been summoned", threaded= True)

def farewell():
    L1.config(text = "Goodbye")


L1 = Label(win, text = "Press a button")
L1.grid(row= 0, column= 0, columnspan= 2, padx = 20, pady = 20)
b1 = Button(win, text = "Click Me", width= 7, command=greeting).grid(row= 1, column= 0, padx = 20)
b2 = Button(win, text = "Farewell", width= 7, command=farewell) .grid(row = 1, column= 1, padx = 20)

win.mainloop()

Solution

  • In tkinter if you add a widget in the window in this way:

    btn = Button().grid()
    

    you lose the control on the widget because the .grid() method returns None.

    The correct way is:

    btn = Button()
    btn.grid()
    

    you can understand why if you create a custom class:

    class Person:
        def __init__(self, name: str):
            self.name = name
    
        def get_name(self):
            return self.name
    
    
    if __name__ == "__main__":
        p = Person(name="Alex")
        print(type(p))
    
        p = Person(name="Alex").get_name()
        print(type(p))
    

    output

    <class '__main__.Person'>
    <class 'str'>