Search code examples
classtkinterfunctiontoplevel

How to call a function inside the same class that destroys the Toplevel window? (Python, Tkinter)


I am not a programmer, just a hobbist, so I would be glad if you could tell me the "pythonic way" solution for my problem.

What I want:

I want to create a Menu with tkinter that has a "New Game", a "Settings" and an "Exit" button, and if I click on the "Exit" button, I want an "Are You Sure?" pop-up window that has a "Yes" and a "No" button, and if i click on the "No" button, I want to destroy the "Are You Sure?" pop-up window.

What's happening:

The "New Game" and the "Settings" buttons are working exactly how I want, but when I click on the "Exit" button, and I get the "Are You Sure?" pop-up window, I get this error:

name 'varAreYouSureToplevel' is not defined

If this is NOT the correct way, please let me know how it's usually made.

I am learning how to write classes, and it's a bit confusing for me, when I try to use Tkinter inside a class.

If you have a solution for this (using Tkinter root and Toplevel) WITHOUT writing classes, then I would be very glad to see it!

I am using Python 3.4

Thank You for your help!

NameError - Image

Here's my code:

from tkinter import *
import os


class classMainMenu(Frame):

    def __init__(self, varRoot):
        Frame.__init__(self, varRoot)
        self.grid()
        self.funcMainMenu()

    def funcMainMenu(self):
        self.varNewGameButton = Button(self, text="New Game", command=self.funcNewGame)
        self.varNewGameButton.grid(row=0, column=0)

        self.varSettingsButton = Button(self, text="Settings", command=self.funcSettingsMenu)
        self.varSettingsButton.grid(row=1, column=0)

        self.varExitButton = Button(self, text="Exit", command=self.funcExit)
        self.varExitButton.grid(row=2, column=0)

    def funcNewGame(self):
        self.varNewGameButton.destroy()        
        self.varSettingsButton.destroy()        
        self.varExitButton.destroy()        
        print("New Game")

    def funcSettingsMenu(self):
        self.varNewGameButton.destroy()        
        self.varSettingsButton.destroy()        
        self.varExitButton.destroy()        
        print("Settings")

    def funcExit(self):
        self.varAreYouSureToplevel = Toplevel(self)
        self.varAreYouSureToplevel.title("Are you sure?")

        self.varAreYouSureTextLabel = Label(varAreYouSureToplevel, text="Are you sure you want to exit?") # HERE IT SAYS: NameError: name 'varAreYouSureToplevel' is not defined
        self.varAreYouSureTextLabel.grid(row=3, column=0)

        self.varAreYouSureYesButton = Button(varAreYouSureToplevel, text="Yes", command=self.funcExitToDesktop)
        self.varAreYouSureYesButton.grid(row=4, column=0)

        self.varAreYouSureNoButton = Button(varAreYouSureToplevel, text="No", command=self.funcDestroyToplevel)
        self.varAreYouSureNoButton.grid(row=4, column=1)

    def funcDestroyToplevel(self):
        self.varAreYouSureToplevel.destroy

    def funcExitToDesktop(self):
        os._exit(1)


varRoot = Tk()


objectMainMenu = classMainMenu(varRoot)
objectMainMenu.mainloop()

Solution

  • In funcExit() you have e.g. Label(varAreYouSureToplevel) (and Button x2).

    varAreYouSureToplevel is an attribute of self, but you are referring to it without the self., so Python is looking in the global namespace, and you get the error you are observing.

    Change these three statements to e.g.

    Label(self.varAreYouSureToplevel and Button(self.varAreYouSureToplevel

    And your code works just fine.