[英]Python Function/Button Reference/Scope Error
I'm trying to create a simple card game. 我正在尝试创建一个简单的纸牌游戏。 It features a main menu with 4 buttons and 2 images.The 4 buttons are war
, garbage
, instruct
, and quit_exe
. 它具有一个主菜单,带有4个按钮和2个图像。这4个按钮是war
, garbage
, instruct
和quit_exe
。 The war
button should command=self.game_war
when it is clicked, and the same for garbage. 当单击war
按钮时,应该为command=self.game_war
,对于垃圾也应如此。 instruct
should show how to play, and quit_exe
should simply quit the application. instruct
应该显示如何播放,而quit_exe
应该只是退出应用程序。 Let's take war
for this problem I have. 让我们为我war
的这个问题而war
。
I need to have, when clicked, war
execute the def game_war(self)
function when it is clicked. 单击时,我需要war
执行def game_war(self)
函数。 When this is clicked, it should grid_forget()
all the widgets so that it can generate widgets for the game of war
. 单击此按钮后,它应该grid_forget()
所有小部件,以便它可以为war
游戏生成小部件。 It should also, when a button called return
is clicked, it clears the widgets, and then regenerates the main menu. 当单击一个名为return
的按钮时,它也应该清除小部件,然后重新生成主菜单。
It needs to be able to start a game based on a button being clicked, and the game functions should be able to use the variables already referenced to use, overwrite, and save those variables, so that it can forget the widgets and place new ones. 它需要能够基于被单击的按钮来启动游戏,并且游戏功能应该能够使用已经引用的变量来使用,覆盖和保存这些变量,以便它可以忘记小部件并放置新的小部件。 。 When the game ends , it should forget the current widgets, use the pre-referenced variables , then regenerate the main menu. 游戏结束时 ,应该忘记当前的小部件, 使用预先引用的变量 ,然后重新生成主菜单。
I get a local variable referenced before assignment error. 我在分配错误之前得到了引用的局部变量。 I tried using nonlocal
and global
, but it doesn't seem to work. 我尝试使用nonlocal
和global
,但似乎不起作用。 I need this as this is a requirement. 我需要这个,因为这是必需的。
I need to be able to execute a function that can grab and use variables. 我需要能够执行一个可以捕获和使用变量的函数。 In this case, I need war
to call game_war
, which can access the war
, instruct
, quit_exe
, garbage
, usrCrd
, and cpuCrd
variables to clear them out, then to generate new variables for the game, and then when the game ends, regenerate the main menu widgets. 在这种情况下,我需要war
来调用game_war
,它可以访问war
, instruct
, quit_exe
, garbage
, usrCrd
和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()
You are not saving any variables as instance variables -- they are all local. 您没有将任何变量另存为实例变量-它们都是局部变量。 If you want to save a variable so that you can use it in other methods, save it as an instance: 如果要保存变量以便可以在其他方法中使用它,请将其另存为实例:
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()
... and so on. ... 等等。
On a side note, you should pick a single method of importing tkinter instead of importing it twice. 附带说明,您应该选择一种导入tkinter的方法,而不是两次导入。 I recommend "import tkinter as tk", and then use "tk." 我建议“将tkinter导入为tk”,然后使用“ tk”。 as a prefix to every widget, because global imports can lead to unclear code. 作为每个小部件的前缀,因为全局导入会导致代码不清晰。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.