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.
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:
It throws this error everytime I try run the application:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 |
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() |
Now the problem persists in the code below where it is calling the username variable in the class' innit function:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 |
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" )) |
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