Python Function/Button Reference/Scope 错误
Python Function/Button Reference/Scope Error
我正在尝试创建一个简单的纸牌游戏。它的主菜单有 4 个按钮和 2 个 images.The,4 个按钮是 war
、garbage
、instruct
和 quit_exe
。 war
按钮在被点击时应该是 command=self.game_war
,对于垃圾也是如此。 instruct
应该显示如何玩,quit_exe
应该简单地退出应用程序。我遇到的这个问题就拿war
吧。
目标
我需要在单击时 war
在单击时执行 def game_war(self)
函数。单击此按钮时,它应该 grid_forget()
所有小部件,以便它可以为 war
的游戏生成小部件。它还应该在单击名为 return
的按钮时清除小部件,然后重新生成主菜单。
要求
它需要能够开始一个基于按钮被点击的游戏,游戏功能应该可以使用变量已经引用到使用、覆盖和保存那些变量,这样它就可以忘记 小部件并放置新的小部件。当游戏结束时,应该忘记当前的widgets,使用预引用的变量,然后重新生成主菜单。
问题
我在赋值错误之前得到了引用的局部变量。我尝试使用 nonlocal
和 global
,但它似乎不起作用。我需要这个,因为这是一项要求。
总结
我需要能够执行一个可以获取和使用变量的函数。在这种情况下,我需要war
调用game_war
,它可以访问war
、instruct
、quit_exe
、garbage
、[=36] =], 和 cpuCrd
变量来清除它们,然后为游戏生成新的变量,然后当游戏结束时,重新生成主菜单小部件。
import tkinter
import winsound
from tkinter import *
from PIL import Image, ImageTk
from random import randint, randrange
class CardGame(tkinter.Frame):
def __init__(self, root):
tkinter.Frame.__init__(self, root)
#define variables for cards
crdImg = []
usrStk = None
cpuStk = None
#define card images
i = 1
while i < 57:
i = i + 1
crdImg.append('img/cards/%s.png' % (i - 1))
usrStk = crdImg[54]
cpuStk = crdImg[55]
#define card stacks
usrCrdImg = Image.open(usrStk)
usrCrdBg = ImageTk.PhotoImage(usrCrdImg)
usrCrd = tkinter.Label(root, image=usrCrdBg)
usrCrd.image = usrCrdBg
cpuCrdImg = Image.open(cpuStk)
cpuCrdBg = ImageTk.PhotoImage(cpuCrdImg)
cpuCrd = tkinter.Label(root, image=cpuCrdBg)
cpuCrd.image = cpuCrdBg
#define empty cell generation
def empCell(px, py, r, c):
grid(padx=px, pady=py, row=r, column=c)
#define buttons
war = tkinter.Button(self, text="Play War!", command=self.game_war)
garbage = tkinter.Button(self, text="Play Caravan!", command=self.game_garbage)
instruct = tkinter.Button(self, text="How to Play", command=self.instruct)
quit_exe = tkinter.Button(self, text="Quit", command=quit)
#define layout
usrCrd.grid(row=1, column=1)
cpuCrd.grid(row=1, column=4)
war.grid(row=2, column=2)
garbage.grid(row=3, column=2)
instruct.grid(row=4, column=2)
quit_exe.grid(row=5, column=2)
#define game functions
def game_war(self):
war.grid_forget()
garbage.grid_forget()
instruct.grid_forget()
quit_exe.grid_forget()
usrCrd.grid_forget()
cpuCrd.grid_forget()
print("Debug")
def game_garbage(self):
print("Debug")
def instruct(self):
print("Debug")
if __name__=='__main__':
root = Tk()
root.columnconfigure(1, weight=1)
root.rowconfigure(1, weight=1)
CardGame(root).grid(row=5, column=3)
root.wm_title('Card Game')
root.mainloop()
您没有将任何变量保存为实例变量——它们都是局部变量。如果要保存变量以便在其他方法中使用它,请将其保存为实例:
self.war = Button(self, text="Play War!", command=self.game_war)
self.garbage = Button(self, text="Play Caravan!", command=self.game_garbage)
self.instruct = Button(self, text="How to Play", command=self.instruct)
self.quit_exe = Button(self, text="Quit", command=quit)
...
self.war.grid_forget()
self.garbage.grid_forget()
self.instruct.grid_forget()
self.quit_exe.grid_forget()
...等等。
附带说明一下,您应该选择一种导入 tkinter 的方法,而不是导入两次。我推荐 "import tkinter as tk",然后使用 "tk." 作为每个小部件的前缀,因为全局导入会导致代码不清晰。
我正在尝试创建一个简单的纸牌游戏。它的主菜单有 4 个按钮和 2 个 images.The,4 个按钮是 war
、garbage
、instruct
和 quit_exe
。 war
按钮在被点击时应该是 command=self.game_war
,对于垃圾也是如此。 instruct
应该显示如何玩,quit_exe
应该简单地退出应用程序。我遇到的这个问题就拿war
吧。
目标
我需要在单击时 war
在单击时执行 def game_war(self)
函数。单击此按钮时,它应该 grid_forget()
所有小部件,以便它可以为 war
的游戏生成小部件。它还应该在单击名为 return
的按钮时清除小部件,然后重新生成主菜单。
要求
它需要能够开始一个基于按钮被点击的游戏,游戏功能应该可以使用变量已经引用到使用、覆盖和保存那些变量,这样它就可以忘记 小部件并放置新的小部件。当游戏结束时,应该忘记当前的widgets,使用预引用的变量,然后重新生成主菜单。
问题
我在赋值错误之前得到了引用的局部变量。我尝试使用 nonlocal
和 global
,但它似乎不起作用。我需要这个,因为这是一项要求。
总结
我需要能够执行一个可以获取和使用变量的函数。在这种情况下,我需要war
调用game_war
,它可以访问war
、instruct
、quit_exe
、garbage
、[=36] =], 和 cpuCrd
变量来清除它们,然后为游戏生成新的变量,然后当游戏结束时,重新生成主菜单小部件。
import tkinter
import winsound
from tkinter import *
from PIL import Image, ImageTk
from random import randint, randrange
class CardGame(tkinter.Frame):
def __init__(self, root):
tkinter.Frame.__init__(self, root)
#define variables for cards
crdImg = []
usrStk = None
cpuStk = None
#define card images
i = 1
while i < 57:
i = i + 1
crdImg.append('img/cards/%s.png' % (i - 1))
usrStk = crdImg[54]
cpuStk = crdImg[55]
#define card stacks
usrCrdImg = Image.open(usrStk)
usrCrdBg = ImageTk.PhotoImage(usrCrdImg)
usrCrd = tkinter.Label(root, image=usrCrdBg)
usrCrd.image = usrCrdBg
cpuCrdImg = Image.open(cpuStk)
cpuCrdBg = ImageTk.PhotoImage(cpuCrdImg)
cpuCrd = tkinter.Label(root, image=cpuCrdBg)
cpuCrd.image = cpuCrdBg
#define empty cell generation
def empCell(px, py, r, c):
grid(padx=px, pady=py, row=r, column=c)
#define buttons
war = tkinter.Button(self, text="Play War!", command=self.game_war)
garbage = tkinter.Button(self, text="Play Caravan!", command=self.game_garbage)
instruct = tkinter.Button(self, text="How to Play", command=self.instruct)
quit_exe = tkinter.Button(self, text="Quit", command=quit)
#define layout
usrCrd.grid(row=1, column=1)
cpuCrd.grid(row=1, column=4)
war.grid(row=2, column=2)
garbage.grid(row=3, column=2)
instruct.grid(row=4, column=2)
quit_exe.grid(row=5, column=2)
#define game functions
def game_war(self):
war.grid_forget()
garbage.grid_forget()
instruct.grid_forget()
quit_exe.grid_forget()
usrCrd.grid_forget()
cpuCrd.grid_forget()
print("Debug")
def game_garbage(self):
print("Debug")
def instruct(self):
print("Debug")
if __name__=='__main__':
root = Tk()
root.columnconfigure(1, weight=1)
root.rowconfigure(1, weight=1)
CardGame(root).grid(row=5, column=3)
root.wm_title('Card Game')
root.mainloop()
您没有将任何变量保存为实例变量——它们都是局部变量。如果要保存变量以便在其他方法中使用它,请将其保存为实例:
self.war = Button(self, text="Play War!", command=self.game_war)
self.garbage = Button(self, text="Play Caravan!", command=self.game_garbage)
self.instruct = Button(self, text="How to Play", command=self.instruct)
self.quit_exe = Button(self, text="Quit", command=quit)
...
self.war.grid_forget()
self.garbage.grid_forget()
self.instruct.grid_forget()
self.quit_exe.grid_forget()
...等等。
附带说明一下,您应该选择一种导入 tkinter 的方法,而不是导入两次。我推荐 "import tkinter as tk",然后使用 "tk." 作为每个小部件的前缀,因为全局导入会导致代码不清晰。