pythonfunctiontkintertoplevel

I keep getting AttributeError: 'Toplevel' object has no attribute 'addtolist' when trying to call functions inside my toplevel class


I'm trying to use my function addtolist(self) within my TopSoftwareWindow() class and I keep getting

AttributeError: 'Toplevel' object has no attribute 'addtolist'

Here's the code for the specific class I'm trying to fix

class TopSoftwareWindow(ttk.Frame): 
    def __init__(self):
        self = tk.Toplevel()
        self.geometry("800x600")
        self.resizable(False, False)
        self.title("Software Window")
        self.iconbitmap('MediaTracker_Icon.ico') 
        
        # Everything that appears on this window
        self.Entry_Field = ttk.Entry(self)

        self.Text_List = tk.Listbox(self)
        self.Category_List = tk.Listbox(self)

        self.New_Entry_Btn = ttk.Button(self, text="New Entry", command=self.addtolist)
        self.Save_File_Btn = ttk.Button(self, text="Save File")
        self.Load_File_Btn = ttk.Button(self, text="Load File")
        self.Quit_Btn = ttk.Button(self, text="Quit")

        self.Entry_Field.place(x= 0, y= 0, width= 724)
        
        self.New_Entry_Btn.place(x= 725, y= 0)
        
        self.Text_List.place(x= 0, y= 25, width= 625, height= 570)
        self.Category_List.place(x= 626, y= 25, width= 99, height= 570)

        self.Save_File_Btn.place(x= 725, y= 25)
        self.Load_File_Btn.place(x= 725, y= 50)
        self.Quit_Btn.place(x= 725, y= 570)

    def addtolist(self):
        text = self.Entry_Field.get()
        if text:
            self.Text_List.insert(tk.END, text)
            self.Entry_Field.delete(0, tk.END)

I just want the ability to add this stuff to the text list inside the GUI but this is causing the entire window not to show.

This is for an academic assignment.


Solution

  • The problem is you're overriding self (which you really never want/need to do) here:

    self = tk.Toplevel()
    

    That said, I suspect you don't even need a Toplevel window here. If you're trying to set up a tkinter app, you can/should just inherit from tk.Tk in your main class like so:

    import tkinter as tk
    from tkinter import ttk
    
    
    class TopSoftwareWindow(tk.Tk):  # inherit from Tk in your app's main class
        def __init__(self):
            super().__init__()  # initialize Tk (the superclass)
            # self = tk.Toplevel()  # you don't need this
            self.geometry("800x600")
            self.resizable(False, False)
            self.title("Software Window")
            self.iconbitmap('MediaTracker_Icon.ico')
    
            # Everything that appears on this window
            self.Entry_Field = ttk.Entry(self)
    
            self.Text_List = tk.Listbox(self)
            self.Category_List = tk.Listbox(self)
    
            self.New_Entry_Btn = ttk.Button(self, text="New Entry", command=self.addtolist)
            self.Save_File_Btn = ttk.Button(self, text="Save File")
            self.Load_File_Btn = ttk.Button(self, text="Load File")
            self.Quit_Btn = ttk.Button(self, text="Quit")
    
            self.Entry_Field.place(x= 0, y= 0, width= 724)
    
            self.New_Entry_Btn.place(x= 725, y= 0)
    
            self.Text_List.place(x= 0, y= 25, width= 625, height= 570)
            self.Category_List.place(x= 626, y= 25, width= 99, height= 570)
    
            self.Save_File_Btn.place(x= 725, y= 25)
            self.Load_File_Btn.place(x= 725, y= 50)
            self.Quit_Btn.place(x= 725, y= 570)
    
        def addtolist(self):
            text = self.Entry_Field.get()
            if text:
                self.Text_List.insert(tk.END, text)
                self.Entry_Field.delete(0, tk.END)
    
    
    if __name__ == '__main__':
        app = TopSoftwareWindow()
        app.mainloop()
    

    If you do want TopSoftwareWindow to exist as a Toplevel window (i.e., you want a second window in addition to your root window that isn't defined here) you can instead inherit from tk.Toplevel:

    class TopSoftwareWindow(tk.Toplevel)
    

    As an aside, you should take a moment to familiarize yourself with PEP8, which outlines Python's style guide. In general, CapitalizedNames are reserved for classes (like TopSoftwareWindow) while snake_case_names are used for variables (like entry_field, text_list, etc.)