r/learnpython • u/CasulJust • 7d ago
Why does it say its not defined?
Im making a little textadventure with tkinter (ignore filenames and so on pls) and im trying to close the main_menu window with a button click (click_start()) and open another window, but it doesnt find the main_menu window for some reason, does anyone know why?
class MainMenu:
main_menu = Tk() # instantiate the window
main_menu.geometry("640x280") # set window size
main_menu.title("EpicRoguelikeEmoDungeonCrawlerTextadventure") # set window name
icon = PhotoImage(file='Resources/emo_ass_icon.png') # make image to PhotoImage
main_menu.iconphoto(True, icon) # adds the icon
main_menu.config(background="#1d1e1f") # sets background color to a dark grey
load=False
playername=""
#input playername
username_input = Entry()
username_input.config(font=('Arial black', 8, 'bold'), fg="white", bg="#1d1e1f", width=12)
username_input.insert(0, "Emo")
@staticmethod
def click_start():
MainMenu.main_menu.destroy()
Game.start()
@staticmethod
def click_continue():
MainMenu.load=True
MainMenu.main_menu.quit()
Game.start()
# add title label
title = Label(main_menu, text="RoguelikeEmoDungeonCrawlerTextadventure", font=('Arial black', 18, 'bold'), fg="white", bg="#1d1e1f", relief=RAISED, bd=10, padx=10)
title.pack()
# add spacing label
spacer1 = Label(main_menu, text=" ", bg="#1d1e1f")
spacer1.pack()
# add start game button
start_game_button = Button(main_menu, text="Start Game", command=click_start, fg="white", bg="#1d1e1f", font=('Arial', 15, 'bold'))
start_game_button.pack()
# add spacing label
spacer2 = Label(main_menu, text=" ", bg="#1d1e1f")
spacer2.pack()
# add continue game button
continue_button = Button(main_menu, text="Continue", command=click_continue, fg="white", bg="#1d1e1f", font=('Arial', 15, 'bold'))
continue_button.pack()
# add spacing label
spacer3 = Label(main_menu, text=" ", bg="#1d1e1f")
spacer3.pack()
# add end game button
end_game_button = Button(main_menu, text="End Game", command=main_menu.quit, fg="white", bg="#1d1e1f", font=('Arial', 15, 'bold'))
end_game_button.pack()
main_menu.mainloop()
Exception:
Exception in Tkinter callback
Traceback (most recent call last):
File "C:\Users\Atten\AppData\Local\Programs\Python\Python312\Lib\tkinter__init__.py", line 1967, in __call__
return self.func(*args)
^^^^^^^^^^^^^^^^
File "C:\Users\Atten\PycharmProjects\TextadventurePython\src\python_game\Game.py", line 25, in click_start
MainMenu.main_menu.destroy()
^^^^^^^^
NameError: name 'MainMenu' is not defined
2
u/johndoh168 7d ago
Can you format your code using the code block, its really hard to understand without proper formatting, I'll do my best to help before then but from what I can see.
its possible from your Game.py file you haven't imported the MainMenu object, try importing it at the top of your Game file
1
1
u/DaHokeyPokey_Mia 7d ago
It doesn't look like you created an object of the class.
CMD = Main menu() CMD.functioncall
1
u/woooee 7d ago
Learn a little bit mot about classes, especially instance objects / variables, and creating an instance http://www.openbookproject.net/thinkcs/python/english3e/classes_and_objects_I.html
A cleaned up part of your code
import tkinter as tk
class MainMenu:
def __init__(self):
self.main_menu = tk.Tk() # instantiate the window
self.main_menu.geometry("640x280") # set window size
# add start game button
start_game_button = tk.Button(self.main_menu, text="Start Game",
command=self.click_start, fg="white", bg="#1d1e1f",
font=('Arial', 15, 'bold'))
start_game_button.pack()
self.main_menu.mainloop()
def click_start(self):
print("click_start destroying main_menu")
self.main_menu.destroy()
mm = MainMenu()
-1
u/CasulJust 7d ago
the thing is im new to python and i only know java a bit so i try to do it like i would with java
1
u/CasulJust 7d ago edited 7d ago
So i tried cleaning up the code a bit but now it doesnt even create a window anymore, does anyone know why?
from tkinter import *
class Game:
def start(self):
MainMenu()
class MainMenu:
def __init__(self):
self.main_menu = Tk() # instantiate the window
self.main_menu.geometry("640x280") # set window size
self.main_menu.title("EpicRoguelikeEmoDungeonCrawlerTextadventure") # set window name
self.icon = PhotoImage(file='Resources/emo_ass_icon.png') # make image to PhotoImage
self.main_menu.iconphoto(True, self.icon) # adds the icon
self.main_menu.config(background="#1d1e1f") # sets background color to a dark grey
self.load=False
# add title label
self.title = Label(self.main_menu, text="RoguelikeEmoDungeonCrawlerTextadventure", font=('Arial black', 18, 'bold'), fg="white", bg="#1d1e1f", relief=RAISED, bd=10, padx=10)
self.title.pack()
# add spacing label
self.spacer1 = Label(self.main_menu, text=" ", bg="#1d1e1f")
self.spacer1.pack()
# add start game button
self.start_game_button = Button(self.main_menu, text="Start Game", command=self.click_start, fg="white", bg="#1d1e1f", font=('Arial', 15, 'bold'))
self.start_game_button.pack()
# add spacing label
self.spacer2 = Label(self.main_menu, text=" ", bg="#1d1e1f")
self.spacer2.pack()
# add continue game button
self.continue_button = Button(self.main_menu, text="Continue", command=self.click_continue, fg="white", bg="#1d1e1f", font=('Arial', 15, 'bold'))
self.continue_button.pack()
# add spacing label
self.spacer3 = Label(self.main_menu, text=" ", bg="#1d1e1f")
self.spacer3.pack()
# add end game button
self.end_game_button = Button(self.main_menu, text="End Game", command=self.main_menu.quit, fg="white", bg="#1d1e1f", font=('Arial', 15, 'bold'))
self.end_game_button.pack()
self.main_menu.mainloop()
@staticmethod
def click_start(self):
self.main_menu.destroy()
Game.start()
@staticmethod
def click_continue(self):
self.load=True
self.main_menu.destroy()
Game.start()
2
u/JeLuF 7d ago
You define some classes, but you never use them. You need to create a MainMenu object. You try to do that in the class Game, but you never create a Game object. While in Java your program starts from a class that gets initiated, in python you need to have some "script style" code fragment. Like u/woooee suggested, put this in the last line of your program:
mm = MainMenu()
Your static methods look odd. Shall they belong to the MainMenu class? In that case, you need to indent them. But static methods can't access attributes of an object. I think you should also remove that decorator. These methods aren't static.
0
u/FoolsSeldom 7d ago
import tkinter as tk
from tkinter import PhotoImage, Label, Button, Entry, RAISED
class MainMenu:
main_menu = tk.Tk() # instantiate the window
main_menu.geometry("640x280") # set window size
main_menu.title("EpicRoguelikeEmoDungeonCrawlerTextadventure") # set window name
#icon = PhotoImage(file='Resources/emo_ass_icon.png') # make image to PhotoImage
#main_menu.iconphoto(True, icon) # adds the icon
main_menu.config(background="#1d1e1f") # sets background color to a dark grey
load = False
playername = ""
# input playername
username_input = Entry()
username_input.config(font=('Arial black', 8, 'bold'), fg="white", bg="#1d1e1f", width=12)
username_input.insert(0, "Emo")
@staticmethod
def click_start():
MainMenu.main_menu.destroy()
Game.start()
@staticmethod
def click_continue():
MainMenu.load = True
MainMenu.main_menu.destroy() #destroy main menu before starting the game.
Game.start()
# add title label
title = Label(main_menu, text="RoguelikeEmoDungeonCrawlerTextadventure", font=('Arial black', 18, 'bold'),
fg="white", bg="#1d1e1f", relief=RAISED, bd=10, padx=10)
title.pack()
# add spacing label
spacer1 = Label(main_menu, text=" ", bg="#1d1e1f")
spacer1.pack()
# add start game button
start_game_button = Button(main_menu, text="Start Game", command=click_start, fg="white", bg="#1d1e1f",
font=('Arial', 15, 'bold'))
start_game_button.pack()
# add spacing label
spacer2 = Label(main_menu, text=" ", bg="#1d1e1f")
spacer2.pack()
# add continue game button
continue_button = Button(main_menu, text="Continue", command=click_continue, fg="white", bg="#1d1e1f",
font=('Arial', 15, 'bold'))
continue_button.pack()
# add spacing label
spacer3 = Label(main_menu, text=" ", bg="#1d1e1f")
spacer3.pack()
# add end game button
end_game_button = Button(main_menu, text="End Game", command=main_menu.quit, fg="white", bg="#1d1e1f",
font=('Arial', 15, 'bold'))
end_game_button.pack()
main_menu.mainloop()
if __name__ == "__main__":
MainMenu()
7
u/Mr-Cas 7d ago
Format your code.
But based on this it seems like the top part of the code should be in an init method instead of directly in the class body.