Python 如何使用按钮命令删除Tkinter标签?

Python 如何使用按钮命令删除Tkinter标签?,python,python-3.x,user-interface,tkinter,python-3.7,Python,Python 3.x,User Interface,Tkinter,Python 3.7,我希望我的程序运行时,一旦用户按下Info按钮,一个名为GameInfoLabel的标签就会显示出来,这是由于Info按钮发出了命令。在相同的条件下(如果按下Info按钮),我想添加一个后退按钮,删除/销毁GameInfoLabel 我试图在下面的代码中实现这一点,但我得到了消息 NameError:未定义名称“GameInfoLabel” 如acw1668的注释所述,GameInfoLabel是GameInfo()方法的本地标签。这意味着一旦此方法完成运行,其中声明的任何内容都将停止存在 通常

我希望我的程序运行时,一旦用户按下Info按钮,一个名为
GameInfoLabel
的标签就会显示出来,这是由于Info按钮发出了命令。在相同的条件下(如果按下Info按钮),我想添加一个后退按钮,删除/销毁
GameInfoLabel

我试图在下面的代码中实现这一点,但我得到了消息

NameError:未定义名称“GameInfoLabel”


如acw1668的注释所述,
GameInfoLabel
GameInfo()
方法的本地标签。这意味着一旦此方法完成运行,其中声明的任何内容都将停止存在

通常的解决方案是向函数传递/返回变量以获得结果,例如,游戏信息可以返回标签,但是,由于您希望在事件发生时自动调用这些函数,例如,按下按钮,这并不容易

我相信解决问题的最简单方法是全局(在全局范围内)声明
GameInfoLabel
变量,这并不总是最佳编码实践,但我不确定tkinter是否能够将变量参数传递给事件处理程序,这可能会很复杂

正如acw1668所提到的,您可以在初始化
标签(…)
返回的新标签上立即调用.pack()。然后包装不会返回标签,因此我们会单独返回

这应该行得通,仔细阅读一下

from tkinter import * 

root = Tk() 
root.title("Game Menu") 
root.geometry("1920x1080")  
root.resizable(True, True) 

# Declare any global UI Components
GameInfoLabel = None # Dont set a Label yet

def QuitGameInfo():
    GameInfoLabel.destroy()
    BackInfoButton['state'] = NORMAL

def GameInfo(): 
    RulesNotepad = open("GameInfo.txt",'r')
    Rules = RulesNotepad.read()
    GameInfoLabel = Label(root, text = Rules, fg = "blue", bg = "red", height = "14", width = "140")
    GameInfoLabel.pack()

    BackInfoButton = Button(root, text = "Back", command = QuitGameInfo).pack() 
    RulesNotepad.close()

button3 = Button(root, text = "Info", command = GameInfo, width = "20", height = "3")
button3.pack()

root.mainloop()

该错误是由于
GameInfoLabel
GameInfo()
中的一个局部变量,在
QuitGameInfo()
中无法访问该变量

您可以通过将
GameInfoLabel
声明为全局或通过参数将其传递给
QuitGameInfo()
来修复此错误。同样适用于
BackInfoButton

但是,您需要解决另一个问题:
GameInfoLabel
BackInfoButton
都是
None
,因为它们是
pack()
的结果

下面是使用全局解决方案修改的代码:

from tkinter import * 

root = Tk() 
root.title("Game Menu") 
root.geometry("1920x1080")  
root.resizable(True, True) 

def QuitGameInfo():
    GameInfoLabel.destroy()
    #BackInfoButton['state'] = NORMAL   # why ??? Should it be destroyed as well?
    BackInfoButton.destroy()


def GameInfo():
    global GameInfoLabel, BackInfoButton 
    with open("GameInfo.txt",'r') as RulesNotepad:
        Rules = RulesNotepad.read()
    GameInfoLabel = Label(root, text = Rules, fg = "blue", bg = "red", height = "14", width = "140")
    GameInfoLabel.pack()
    BackInfoButton = Button(root, text = "Back", command = QuitGameInfo)
    BackInfoButton.pack() 

Button(root, text = "Info", command = GameInfo, width = "20", height = "3").pack()

root.mainloop()

但是,我建议使用一个框架来固定
GameInfoLabel
BackInfoButton
,框架最初是隐藏的。单击“信息”按钮时,显示框架。单击“上一步”按钮时,隐藏帧

from tkinter import * 

root = Tk() 
root.title("Game Menu") 
root.geometry("1920x1080")  
root.resizable(True, True) 

def GameInfo():
    with open("GameInfo.txt",'r') as RulesNotepad:
        Rules = RulesNotepad.read()
    GameInfoLabel.config(text=Rules)
    info_frame.pack()  # show the game info frame

Button(root, text="Info", command=GameInfo, width="20", height="3").pack()

# create the game info frame but don't show it initially
info_frame = Frame(root)
GameInfoLabel = Label(info_frame, fg="blue", bg="red", height="14", width="140")
GameInfoLabel.pack()
Button(info_frame, text="Back", command=info_frame.pack_forget).pack()

root.mainloop()

代码中没有什么问题:1)
GameInfoLabel
GameInfo()
中的一个局部变量,因此无法在
QuitGameInfo()中访问它。导致错误的原因;2) 
GameInfoLabel
None
,因为它是
Label(…).pack()的结果;3) 
GameInfoButton
内部
QuitGameInfo()
未定义。为什么要将
BackInfoButton['state']
更改为
NORMAL
,因为它已经处于
NORMAL
状态?我甚至不知道为什么我现在要包含这一行。
from tkinter import * 

root = Tk() 
root.title("Game Menu") 
root.geometry("1920x1080")  
root.resizable(True, True) 

def GameInfo():
    with open("GameInfo.txt",'r') as RulesNotepad:
        Rules = RulesNotepad.read()
    GameInfoLabel.config(text=Rules)
    info_frame.pack()  # show the game info frame

Button(root, text="Info", command=GameInfo, width="20", height="3").pack()

# create the game info frame but don't show it initially
info_frame = Frame(root)
GameInfoLabel = Label(info_frame, fg="blue", bg="red", height="14", width="140")
GameInfoLabel.pack()
Button(info_frame, text="Back", command=info_frame.pack_forget).pack()

root.mainloop()