how a toplevel class can inherite from the main class tkinter opp inorder to access main class's attr

Question:

I want to access the main window attributes and change some of its labels and button’s states in my toplevel class however it can not find them. So I’m not sure how to use opp approach in tkinter and I tried using super__init__ and text variable but I failed. The main problem is inheritance in tkinter frame work and i highlighted it in def login 2. I appreciate the help. peace.

import tkinter as tk
import sqlite3
cnt = sqlite3.connect("simple_store.db")

class MainWindow():
    def __init__(self,master):
        self.master=master
        self.master.geometry('350x200')
        self.master.resizable(False, False)

        self.lbl_msg = tk.Label(self.master, text='')
        self.lbl_msg.pack()

        self.login_btn = tk.Button(self.master, text="Login ", command=login)
        self.login_btn.pack()

        self.submit_btn = tk.Button(self.master, text="Submit", command=submit)
        self.submit_btn.pack()


class submit:
    pass

class login(MainWindow):
    def __init__(self):

        self.login_win = tk.Toplevel()
        self.login_win.title("Login")
        self.login_win.geometry("350x200")

        self.lbl_temp = tk.Label(self.login_win, text='')
        self.lbl_temp.pack()

        self.lbl_user = tk.Label(self.login_win, text='Username:')
        self.lbl_user.pack()

        self.userw = tk.Entry(self.login_win, width=15)
        self.userw.pack()

        self.lbl_pass = tk.Label(self.login_win, text='Password')
        self.lbl_pass.pack()

        self.passwordw = tk.Entry(self.login_win, width=15)
        self.passwordw.pack()

        self.login_btn2 = tk.Button(self.login_win, text="Login", command= self.login2)
        self.login_btn2.pack(pady=20)

        self.login_win.mainloop()

    def login2(self):
        global userid

        self.user = self.userw.get()
        self.password = self.passwordw.get()

        query = '''SELECT * FROM customers WHERE username=? AND PASSWORD=?'''
        result = cnt.execute(query, (self.user, self.password))
        row = result.fetchall()

        if (row):
            self.lbl_temp.configure(text="welcome")
            userid = row[0][0]

            ####the problem is here####

            self.lbl_msg.configure(text="welcome " + self.user)
            # self.login_btn.configure(state="disabled")


            self.userw.delete(0, 'end')
            self.passwordw.delete(0, 'end')
        else:
            self.lbl_temp.configure(text="error")



root = tk.Tk()
window = MainWindow(root)
root.mainloop()
Asked By: mmd-ghamgosar

||

Answers:

Alright so, in order for you to inherit from the main class, you have to make your __init__() method’s signature the same + whatever you might need for the top level class.

Example:

class Parent:
    def __init__(self, attr1):
        self.attr1 = attr1

class Child(Parent):
    def __init__(self, attr1, attr2):
        super().__init__(attr1) # You can manipulate attr1 here
        self.attr2 = attr2
        # You can also manipulate attr1 here using
        # self.attr1 = whatever value.
Answered By: LeTorky

You shouldn’t use inheritance for this. Inheritance is an "is a" relationship. If you inherit from MainWindow than your other window is a MainWindow with extra features. You don’t want two MainWindow instances.

Instead, you need to pass the instance of MainWindow to login.

class MainWindow():
    def __init__(self,master):
        ...
        self.login_btn = tk.Button(self.master, text="Login ", command=self.login)
        ...

    def login(self):
        login_window = login(main_window=self)
        #                    ^^^^^^^^^^^^^^^^

class login():
    def __init__(self, main_window):
        self.main_window = main_window
        ...

    def login2(self):
        ...
        self.main_window.lbl_msg.configure(text="welcome " + self.user)
        #    ^^^^^^^^^^^^
        ...
Answered By: Bryan Oakley