Search code examples
pythonbuttontkinterdestroy

Tkinter .destroy() button causes error when in function


I have a button in my Tkinter window that, when clicked, needs to call two functions: a .get() to store the entry box value and a .destroy() so the window closes when button is pressed.

I must be doing something wrong because whether I put the .destroy() in my grouped function with .get() or put .destroy() as the sole command in the button, I get this error:

AttributeError: 'GuardianLocator' object has no attribute 'frame'

I believe my code is near identical to other answers on this site so I'm not sure why .destroy() isn't working...

from tkinter import *


class GuardianLocator:

    def __init__(self, master):
        self._name = ""
        frame = Frame(master)
        frame.grid()
        master.title("GUARDIAN LOCATOR")

        self.locator_label = Label(frame, text="Which Sailor Guardian are you looking for?", width=40, height=2)
        self.locator_label.grid()

        self.entry = Entry(frame)
        self.entry.grid()

        self.button1 = Button(frame, text="Search", command=self.guardian_name, pady=2)
        self.button1.grid()


    def guardian_name(self):
        self._name = self.entry.get()
        self.frame.destroy()
        return self.entry.get()

EDIT

When I make the recommended changes to the self.frame from the answers, the program runs, but then when I click the button I get this error-

Traceback (most recent call last):
  File "C:\Python34\lib\tkinter\__init__.py", line 1482, in __call__
    return self.func(*args)
  File "C:\Users\david\PycharmProjects\Sailor Moon Hunt\guardian_locator.py", line 25, in guardian_name
    return self.entry.get()
  File "C:\Python34\lib\tkinter\__init__.py", line 2484, in get
    return self.tk.call(self._w, 'get')
_tkinter.TclError: invalid command name ".45213328.45795632"

It appears to be referring to the .get() call, but that was working fine before I made the self.frame changes. Does anyone know what that error means?


Solution

  • change this code:

    def __init__(self, master):
        self._name = ""
        frame = Frame(master)
        frame.grid()
        master.title("GUARDIAN LOCATOR")
    

    with the following:

    def __init__(self, master):
        self._name = ""
        self.frame = Frame(master)
        self.frame.grid()
        master.title("GUARDIAN LOCATOR")