1

I am trying to make a tkinter desktop application (Notepad) using classes but I found an Attribute Error in my code. I made three files "menu_option.py", "textarea.py" and "window_frame.py". Run the "menu_option.py" file so that you found the error. I am using python (3.9). Also is there any another way to connect "new_file" function to menu item. Here is my code below:

menu_option.py

from tkinter import *
from textarea import TextArea
from window_frame import Window


class Menu_Option(TextArea):
    file = None

    def __init__(self, master, newfile=None):
        super().__init__(root)
        self.Menubar = 'MenuBar'
        self.Filemenu = 'FileMenu'
        self.root = self.root
        self.master = self.master
        self.newfile = newfile

    def launch(self):
        self.Menubar = Menu(self.root)
        
        self.Filemenu = Menu(master=self.Menubar, tearoff=0)
        self.Filemenu.add_command(label='New File...', command=self.newfile)
        self.Menubar.add_cascade(label='File', menu=self.Filemenu)
        
        self.root.config(menu=self.Menubar)


class Features(Menu_Option):
    def __init__(self, master):
        super().__init__(master, newfile=self.new_file)

    def new_file(self):
        global file
        self.root.title(self.title)
        file = None
        self.textarea.delete(1.0, END)


if __name__ == '__main__':
    root = Tk()
    Window(root).launch()
    TextArea(root).launch()
    Menu_Option(root).launch()
    Features(root).launch()
    root.mainloop()

textarea.py

from tkinter import *
from window_frame import Window
from tkinter.scrolledtext import ScrolledText


class TextArea(Window):
    def __init__(self, name):
        super().__init__(name)
        self.name = self.root
        self.master = 'root'
        self.textarea = 'text_area'
        self.font = 'courier 14 normal'

    def launch(self):
        self.textarea = ScrolledText(self.root, font=self.font)
        self.textarea.pack(expand=True, fill=BOTH)


if __name__ == '__main__':
    root = Tk()
    Window(root).launch()
    TextArea(root).launch()
    root.mainloop()

window_frame.py

from tkinter import *

class Window:

    def __init__(self, root):
        self.root = root
        self.geometry = '1000x550+100+100'
        self.title = 'Untitled - ProBook'

    def launch(self):
        self.root.geometry(self.geometry)
        self.root.title(self.title)


if __name__ == '__main__':
    root = Tk()
    Window(root).launch()
    root.mainloop()

Error:

Exception in Tkinter callback
Traceback (most recent call last):
  File "D:\Installed Programs\Python\lib\tkinter\__init__.py", line 1892, in __call__
    return self.func(*args)
  File "C:\Users\vaish\OneDrive\ProBook\menu_option.py", line 35, in new_file
    self.textarea.delete(1.0, END)
AttributeError: 'str' object has no attribute 'delete'
1
  • 1
    When you are asking about an error, always include the full traceback. Commented May 19, 2021 at 3:53

2 Answers 2

1

Since Menu_Option() has override launch() function, therefore TextArea.launch() will not be executed and so instance variable textarea is still a string.

If child class wants to inherit parent class launch() functionality, you need to call the parent class launch() in its launch() function:

textarea.py

class TextArea(Window):
    ...

    def launch(self):
        super().launch()  # call parent class launch()
        self.textarea = ScrolledText(self.root, font=self.font)
        self.textarea.pack(expand=True, fill=BOTH)

menu_option.py

class Menu_Option(TextArea):
    ...

    def launch(self):
        super().launch()  # execute parent class launch()
        ...

...

if __name__ == "__main__":
    root = Tk()
    #Window(root).launch()       # <- no need to execute
    #TextArea(root).launch()     # <- no need to execute
    #Menu_Option(root).launch()  # <- no need to execute
    Features(root).launch()
    root.mainloop()

Note that Window(root).launch(), TextArea(root).launch() and Menu_Option(root).launch() are not required.

Sign up to request clarification or add additional context in comments.

Comments

1

You have initialized self.textarea="text_area" in textarea.py . But when you import it in menu_option.py, you are overwriting the function launch, which is supposed to set the value of self.textarea to a ScrolledText and pack it. To solve this you have to include the code in launch function of textarea.py in the function launch of Menu_Option class.

from tkinter import *
from tkinter.scrolledtext import ScrolledText
from textarea import TextArea
from window_frame import Window


class Menu_Option(TextArea):
    file = None

    def __init__(self, master, newfile=None):
        super().__init__(root)
        self.Menubar = 'MenuBar'
        self.Filemenu = 'FileMenu'
        self.root = self.root
        self.master = self.master
        self.newfile = newfile

    def launch(self):
        self.Menubar = Menu(self.root)

        #You have to include these 2 lines of code which were overwritten
        self.textarea = ScrolledText(self.root, font=self.font)
        self.textarea.pack(expand=True, fill=BOTH)

        self.Filemenu = Menu(master=self.Menubar, tearoff=0)
        self.Filemenu.add_command(label='New File...', command=self.newfile)
        self.Menubar.add_cascade(label='File', menu=self.Filemenu)
    
        self.root.config(menu=self.Menubar)

1 Comment

Now my code runs successfully, thanks for helping me...@pyNeophyte

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.