pythontkinterinheritancesubclasstoplevel

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


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()

Solution

  • 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)
            #    ^^^^^^^^^^^^
            ...