Home > Software design >  AttributeError: '_tkinter.tkapp' object has no attribute 'add'
AttributeError: '_tkinter.tkapp' object has no attribute 'add'

Time:04-23

I'm generating a tkinter application, and .I need to adopt it with classes and objects. The examples that I tried gives me the error, AttributeError: '_tkinter.tkapp' object has no attribute 'add'. This is the working example.

import tkinter as tk
from tkinter import ttk
from PIL import Image, ImageTk
from tkinter.filedialog import askopenfile
from tkinter.font import Font

class App(tk.Tk):
    def __init__(self):
        super().__init__()

        # intializing the window
        root = self
        root.title("Data Visualization")

        # configuring size of the window
        root.geometry('800x650')
        
        # this removes the maximize button
        root.resizable(0,0)

        # Styling the tabs
        s = ttk.Style()
        s.theme_create('pastel', settings={
            ".": {
                "configure": {
                    "background": '#ffffff', # All except tabs
                    "font": 'red'
                }
            },
            "TNotebook": {
                "configure": {
                    "background":'#848a98', # Your margin color
                    "tabmargins": [5, 5, 4, 4], # margins: left, top, right, separator
                }
            },
            "TNotebook.Tab": {
                "configure": {
                    "background": '#d9ffcc', # tab color when not selected
                    "padding": [10, 2], # [space between text and horizontal tab-button border, space between text and vertical tab_button border]
                    "font":"white"
                },
                "map": {
                    "background": [("selected", '#ccffff')], # Tab color when selected
                    "expand": [("selected", [1, 1, 1, 0])] # text margins
                }
            }
        })

        s.theme_use('pastel')
        #s.theme_use('default')
        s.configure('TNotebook.Tab', font=('URW Gothic L','13','bold'))
        #s.map("TNotebook", background= [("selected", "#ffffff")])
   
        my_font = Font(
            family = 'Arial',
            size = 15,
            weight = 'bold',
            slant = 'roman',
            underline = 0,
            overstrike = 0
        )
    
        my_font2 = Font(
            family = 'Arial',
            size = 11,
            #weight = 'bold',
            slant = 'roman',
            underline = 0,
            overstrike = 0
        )
    
        #Create Tab Control
        notebook = ttk.Notebook(root)

        # Configuration inside each tab
        f1 = tk.Frame(notebook,background="#FFFAF0")
        f2 = tk.Frame(notebook,background="#ffffff")
        f3 = tk.Frame(notebook,background="#ffffff")
        f4 = tk.Frame(notebook,background="#ffffff")

        # Configure tab titles
        notebook.add(f1, text="About" )
        notebook.add(f2, text="Load and Save Actions" )
        notebook.add(f3, text="Preprocess" )
        notebook.add(f4, text="Visualize" )
        
        
        
        #Tab Name Labels
        #ttk.Label(f1, text="This is Tab 1").grid(column=3, row=2)
        ttk.Label(f2, text="This is Tab 2").grid(column=2, row=2)
        
        #logo
        logo = Image.open('airport.jpg')
        #Resize the Image using resize method
        resized_image= logo.resize((600,300), Image.ANTIALIAS)
        logo = ImageTk.PhotoImage(resized_image)
        logo_label = ttk.Label(f1,image=logo,relief="raised")
        logo_label.image = logo
        #logo_label.grid(column=3, row=0)
        logo_label.place(relx=0.12,rely=0.1) # using place
        
        # Tab1
        ttk.Label(f1, text="Airports, Airport-frequencies and Runways analysis", font=my_font).place(relx=0.2,rely=0.03)
        #label = tk.Label(f1, text="This application allows you to analyze Airports, Airport-frequencies and Runways \n of Europe", font=my_font2).place(rely=0.63,anchor="center")

        #text box
        
        text_box = tk.Text(f1, height =10,font=my_font2)
        text_box.insert(1.0,"""This application allows you to analyze Airports, Airport-frequencies and Runways of Europe.
        
        • Tab "Load and Save Actions" is to load the initial data set (which consists of three CSV files) and translate it into a suitable format. \n\n• Tab "Preprocess" is to clean and prepare the initial data set, managing inconsistences, \nerrors, missing values and any specific changes required. \n\n• Tab "Visualize" is to use the prepared data set to generate output and visualisations.""" )
        text_box.tag_configure("center", justify="center")
        text_box.tag_add("center", 1.0, "end")
        text_box.place(relx=0.1, rely=0.65)
        text_box.config(highlightthickness = 2, borderwidth=0,background='#FFFAFA')
        notebook.pack(expand=1, fill="both")
        
        

if __name__ == "__main__":
    app = App()
    app.mainloop()

I tried to break this into classes like below. The classes should be ideal to have like, the main header class, tabs class and tabs class needs to be inherited tab wise. Can someone please help

import tkinter as tk
from tkinter import ttk
from PIL import Image, ImageTk
from tkinter.filedialog import askopenfile
from tkinter.font import Font

class App(tk.Tk):
    def __init__(self):
        super().__init__()
        # intializing the window
        self.title("Data Visualization")

        # configuring size of the window
        self.geometry('800x650')
        
        # this removes the maximize button
        self.resizable(0,0)

        

    def tabs(self):

        notebook = self
        f1 = tk.Frame(notebook,background="#FFFAF0")
        notebook.add(f1, text="About" )
        #logo
        logo = Image.open('airport.jpg')
        #Resize the Image using resize method
        resized_image= logo.resize((600,300), Image.ANTIALIAS)
        logo = ImageTk.PhotoImage(resized_image)
        logo_label = ttk.Label(f1,image=logo,relief="raised")
        logo_label.image = logo
        #logo_label.grid(column=3, row=0)
        logo_label.place(relx=0.12,rely=0.1) # using place
        
        # Tab1
        ttk.Label(f1, text="Airports, Airport-frequencies and Runways analysis", font=my_font).place(relx=0.2,rely=0.03)
        #label = tk.Label(f1, text="This application allows you to analyze Airports, Airport-frequencies and Runways \n of Europe", font=my_font2).place(rely=0.63,anchor="center")

        #text box
        
        text_box = tk.Text(f1, height =10,font=my_font2)
        text_box.insert(1.0,"""This application allows you to analyze Airports, Airport-frequencies and Runways of Europe.
        
        • Tab "Load and Save Actions" is to load the initial data set (which consists of three CSV files) and translate it into a suitable format. \n\n• Tab "Preprocess" is to clean and prepare the initial data set, managing inconsistences, \nerrors, missing values and any specific changes required. \n\n• Tab "Visualize" is to use the prepared data set to generate output and visualisations.""" )
        text_box.tag_configure("center", justify="center")
        text_box.tag_add("center", 1.0, "end")
        text_box.place(relx=0.1, rely=0.65)
        text_box.config(highlightthickness = 2, borderwidth=0,background='#FFFAFA')
        notebook.pack(expand=1, fill="both")
        
        

if __name__ == "__main__":
    
    App().tabs()
    app.mainloop()

CodePudding user response:

The problem is here:

class App(tk.Tk):
    .
    .
    .
    def tabs(self):
        notebook = self  # <- HERE (see below)
        f1 = tk.Frame(notebook, background="#FFFAF0")
        notebook.add(f1, text="About" )

Because tabs() is a method inside of your App(tk.Tk) class, it inherits attributes from tk.Tk directly thanks to super().__init__() - which is to say that self in tabs() refers to class attributes from tk.Tk!

Basically, notebook = tk.Tk(), and tk.Tk() doesn't have an add() method!

I assume you want an actual Tk Notebook widget, so try:

def tabs(self):
    # create a new Notebook widget with App as its parent
    notebook = tk.Notebook(self)  # <- do this instead!
    f1 = tk.Frame(notebook, background="#FFFAF0")
    notebook.add(f1, text="About" )
  • Related