Aug-03-2023, 08:56 PM
I was following up with multiple tutorials online for designing a tkinter gui app for a password manager program I made recently, and so I split up the app into a package of multiple python scripts, with the __innit__.py file of the package containg the parent root class and then multiple other scripts containing tk.frame classes, all inheriting from the parent class.
Now the problem persists in the code below where it is calling the username variable in the class' innit function:
from .home import * from .register import * from .login import * from .menu import * from .store import * from .retrieve import * from PIL import Image, ImageTk import tkinter as tk class App(tk.Tk): def __init__(self, *args, **kwargs): tk.Tk.__init__(self, *args, **kwargs) self.configure(bg="black") self.geometry("500x500+500+100") self.minsize(500, 500) self.maxsize(500, 500) self.title("The Vault v1.0") self.home = ImageTk.PhotoImage( Image.open('./interface/Home.png').resize((35, 30), Image.ANTIALIAS)) container = tk.Frame(self) container.pack(side="top", fill="both", expand=True) container.grid_rowconfigure(0, weight=1) container.grid_columnconfigure(0, weight=1) #container.configure(bg="black", highlightbackground="white", highlightthickness=2) self.frames = {} for F in (home, register, login, menu, store, retrieve): page_name = F.__name__ frame = F(parent=container, controller=self) self.frames[page_name] = frame frame.grid(row=0, column=0, sticky="nsew") self.show_frame("home") self.bind('<Escape>', lambda x: self.destroy()) global username def exit(self): self.destroy() def show_frame(self, page_name): frame = self.frames[page_name] frame.tkraise() frame.focus_set() self.unbinder() frame.binds() def unbinder(self): self.unbind('<Return>') self.unbind('1') self.unbind('2') self.unbind('3') self.unbind('4') self.unbind('5') def exitButton(self, frame): note = tk.Label(self, bg= "black", fg="white", text="(esc)", font=("Terminal", 10)) exitBut = tk.Button(frame, bg= "black", fg="white", text='EXIT', font=("Terminal", 20), command=exit, activebackground="black", relief=tk.SOLID, borderwidth=0, padx=0, pady=0, cursor="hand2") exitBut.place(relx=0.9, rely=0.9, y=-10,anchor=tk.CENTER) note.place(relx=0.9, rely=0.9, x=-8, y=10, anchor=tk.CENTER) def homeButton(self, frame): def home_clear(self): self.show_frame('home') self.username = "" buttn = tk.Button(frame, image=self.home, bg="black", command=lambda: home_clear(self), activebackground="black", relief=tk.SOLID, borderwidth=0, padx=0, pady=0, cursor="hand2") buttn.place(relx=0.05, rely=0.05) def start(): app = App() app.mainloop()In the above __innit__.py file, there is a global variable username which needs to be passed on to and modified by other classes so that they may call various backend function using 'username' as a parameter.
Now the problem persists in the code below where it is calling the username variable in the class' innit function:
import tkinter as tk from customtkinter import CTkComboBox, CTkTextbox from .backend import * class retrieve(tk.Frame): def __init__(self, parent, controller): self.controller = controller tk.Frame.__init__(self, parent, bg="black", highlightthickness=5, highlightcolor='white') self.controller = controller head = tk.Label(self, bg="black", fg="white", text="STORED DATA", font=("Terminal", 32)) # retrieve _passwords: returns a list of tuples split in two lists with same number of elements. services, data = retrieve_passwords(self.controller.username) # THIS THROWS ERROR service_list.configure(values=services) def combobox_callback(choice): data_out = data[services.index(choice)] data_disp.insert("0.0", data_out) print("combobox dropdown clicked:", choice) service_list = CTkComboBox(self, fg_color="black", text_color="white", font=("Terminal", 20, "bold"), justify="left", corner_radius=0, width=450, height=36, border_width=0, border_color="white", command=combobox_callback, dropdown_fg_color="black", dropdown_text_color="white", dropdown_font=("Terminal", 20, "bold"),hover=False, button_color="black", button_hover_color="white", dropdown_hover_color="black") service_list.set(">SERVICE NAME") data_disp = CTkTextbox(self, fg_color="black", text_color="white", font=("Terminal", 22, "bold"), scrollbar_button_color="white", scrollbar_button_hover_color="white",wrap=tk.WORD, corner_radius=0, width=450, height=250, border_width=0) data_disp.configure(state=tk.DISABLED) back = tk.Button(self, bg="black", fg="white", text='BACK', font=("Terminal", 18, "bold"), command=lambda: controller.show_frame("menu"), activebackground="black", relief=tk.SOLID, borderwidth=0, padx=16, pady=0, cursor="hand2") entNote = tk.Label(self,bg="black", fg="white", text="(enter)", font=("Terminal", 10)) head.place(relx=0.5, rely=0.1, anchor=tk.CENTER) service_list.place(relx=0.1, rely=0.3, y=-10,x=-35,anchor=tk.W) data_disp.place(relx=0.1, rely=0.45, x=-30, y=65,anchor=tk.W) back.place(relx=0.5, rely=0.9, anchor=tk.CENTER) entNote.place(relx=0.5, rely=0.9, y=20, anchor=tk.CENTER) controller.exitButton(self) controller.homeButton(self) def binds(self): self.focus_set() self.controller.bind('<Return>', lambda x: self.controller.show_frame("menu"))It throws this error everytime I try run the application:
Error:Traceback (most recent call last):
File "a:/python projects/password generator/main.py", line 3, in <module>
interface.start()
File "a:\python projects\password generator\interface\__init__.py", line 86, in start
app = App()
File "a:\python projects\password generator\interface\__init__.py", line 34, in __init__
frame = F(parent=container, controller=self)
File "a:\python projects\password generator\interface\retrieve.py", line 14, in __init__
services, data = retrieve_passwords(self.controller.username)
File "C:\Users\konstantin\AppData\Local\Programs\Python\Python38\lib\tkinter\__init__.py", line 2345, in __getattr__
return getattr(self.tk, attr)
AttributeError: '_tkinter.tkapp' object has no attribute 'username'
PS: I am fairly new to python classes and tkinter so I might have made some mistakes with the inheritances, just cant figure which ones exactly so any help at all is very much appreciated, thanks