Python Forum
AttributeError: '_tkinter.tkapp' object has no attribute 'username'
Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
AttributeError: '_tkinter.tkapp' object has no attribute 'username'
#1
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.

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
Reply
#2
The error is correct. Class App does not have an attribute named "username" until after homeButton() is called. You should initialize self.username to something in the __init__() method.
Reply
#3
(Aug-03-2023, 10:33 PM)deanhystad Wrote: The error is correct. Class App does not have an attribute named "username" until after homeButton() is called. You should initialize self.username to something in the __init__() method.

I also tried initialising self.username to an empty string inside the __init__() method of the class App like so:
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
        self.username = ""
but it still returns the same attribute error, or perhaps I am doing it wrong. Again, thanks alot for the help
Reply
#4
Still too late, You must assign username before making all the frames.
        self.frames = {}
        for F in (home, register, login, menu, store, retrieve):
            page_name = F.__name__
            frame = F(parent=container, controller=self)    # <-- Error happens here
            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       # <-- This does nothing
        self.username = ""    # <-- You don't assign value to username until here
Thinking is required when programming. You get an error saying that the object does not have an attributed named "username", but obviously the class assigns an instance variable of that name. How is this possible? What sequence of events can result in getting this error? Sit down and look carefully at your code, focusing on where the error is reported and where you are assigning a value to "username". You are doing this:
x = username
username = "a name"
Here the problem is clear. Through careful analysis you can make the problem in your program just as clear. It just requires some thought.
Konstantin23 likes this post
Reply
#5
(Aug-04-2023, 11:54 AM)deanhystad Wrote: Still too late, You must assign username before making all the frames.
        self.frames = {}
        for F in (home, register, login, menu, store, retrieve):
            page_name = F.__name__
            frame = F(parent=container, controller=self)    # <-- Error happens here
            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       # <-- This does nothing
        self.username = ""    # <-- You don't assign value to username until here
Thinking is required when programming. You get an error saying that the object does not have an attributed named "username", but obviously the class assigns an instance variable of that name. How is this possible? What sequence of events can result in getting this error? Sit down and look carefully at your code, focusing on where the error is reported and where you are assigning a value to "username". You are doing this:
x = username
username = "a name"
Here the problem is clear. Through careful analysis you can make the problem in your program just as clear. It just requires some thought.
Wow! that was super helpful, assigned the variable before the frame stack and it worked like a charm :)
also thanks alot for the advice as well, as I am still just a beginner so yes, patience is indeed required specially when working with python oop XD
Reply


Possibly Related Threads…
Thread Author Replies Views Last Post
  getpass.getpass() results in AttributeError: module 'os' has no attribute 'O_NOCTTY' EarthAndMoon 4 788 Oct-03-2023, 02:00 PM
Last Post: deanhystad
  Python: Regex is not good for re.search (AttributeError: 'NoneType' object has no att Melcu54 9 1,517 Jun-28-2023, 11:13 AM
Last Post: Melcu54
  Parallel processing - AttributeError: Can't get attribute 'sktimekmeans' Mohana1983 1 764 Jun-22-2023, 02:33 AM
Last Post: woooee
  Python: AttributeError: 'PageObject' object has no attribute 'extract_images' Melcu54 2 3,924 Jun-18-2023, 07:47 PM
Last Post: Melcu54
  Object attribute behavior different in 2 scripts db042190 1 753 Jun-14-2023, 12:37 PM
Last Post: deanhystad
  Problem with Pyinstaller. No module named '_tkinter' tonynapoli2309 0 1,019 May-15-2023, 02:38 PM
Last Post: tonynapoli2309
  cx_oracle Error - AttributeError: 'function' object has no attribute 'cursor' birajdarmm 1 2,399 Apr-15-2023, 05:17 PM
Last Post: deanhystad
  Pandas AttributeError: 'DataFrame' object has no attribute 'concat' Sameer33 5 5,684 Feb-17-2023, 06:01 PM
Last Post: Sameer33
  Hiding username and password on sql tantony 10 2,952 Oct-21-2022, 07:58 PM
Last Post: wavic
  Pulling username from Tuple pajd 21 3,432 Oct-07-2022, 01:33 PM
Last Post: pajd

Forum Jump:

User Panel Messages

Announcements
Announcement #1 8/1/2020
Announcement #2 8/2/2020
Announcement #3 8/6/2020