pythonpython-3.xtkintertk-toolkitpython-3.6

Confused by root vs self.root and the use of __init__. Also confused with definitions and classes


first:

from tkinter import *


self.root = Tk()
self.root.configure(bg="red", padx=10, pady=10)
self.root.title("WELCOME- PLEASE LOGIN)")

name = Label(self.root, text="Name:", bg="magenta")
password = Label(self.root, text="Password", bg="magenta")
nameentry = Entry(self.root)
passwordentry = Entry(self.root)

name.grid(row=0, sticky=E)
password.grid(row=1, sticky=E)
nameentry.grid(row=0, column=1)
passwordentry.grid(row=1, column=1)

mainloop()

error on this code ( Traceback (most recent call last): File "/Users/me/pythonfolder/frametest.py", line 4, in self.root = Tk() NameError: name 'self' is not defined)

A window opens but is blank.

Next:

from tkinter import *


root = Tk()
root.configure(bg="red", padx=10, pady=10)
root.title("WELCOME- PLEASE LOGIN)")

name = Label(root, text="Name:", bg="magenta")
password = Label(root, text="Password", bg="magenta")
nameentry = Entry(root)
passwordentry = Entry(root)

name.grid(row=0, sticky=E)
password.grid(row=1, sticky=E)
nameentry.grid(row=0, column=1)
passwordentry.grid(row=1, column=1)

mainloop()

This works fine.

Why is using self.root causing an error vs just root?

Also:

from tkinter import *


def __init__(self, Event= None):

    root = Tk()
    root.configure(bg="red", padx=10, pady=10)
    root.title("WELCOME- PLEASE LOGIN)")

    name = Label(root, text="Name:", bg="magenta")
    password = Label(root, text="Password", bg="magenta")
    nameentry = Entry(root)
    passwordentry = Entry(root)

    name.grid(row=0, sticky=E)
    password.grid(row=1, sticky=E)
    nameentry.grid(row=0, column=1)
    passwordentry.grid(row=1, column=1)

mainloop()

Causes this error using init: AttributeError: 'NoneType' object has no attribute 'tk' Using self.root in place of root causes the same error. Removing event= None also causes this error.

Basically, I am confused on self.root vs root, definitions and their errors, and classes.


Solution

  • self is a class level identifier. When you type self.root = Tk() it means in this class it will create a class level variable root and initialize it with Tk() object and whenever you want to access this variable in the class you will call it with self.root like self.root.title()

    A little demo:

    class demo(object):
        def __init__(self, a):
            self.a = a
    
        def change_a(self, new_a):
            self.a = new_a
    
     obj1 = demo(10) # will call the init fn of class and create a class level variable a = 10
     print(obj1.a) # will print 10 which is stored in class level variable for obj1
    
    obj1.change_a(20) # will call the fn and change the class level variable a = 20
    print(obj1.a) # will print 20 becuase class level variable a was changed
    

    It is not as simple as it look's like so but I think now you have a little idea