Python nameerror:tkinter中未定义全局名称

Python nameerror:tkinter中未定义全局名称,python,tkinter,Python,Tkinter,为了brevitys的缘故,这里留下了一些if,但在一些不同的战斗中也是一样的,命名按钮a、b、c、d、e、f等等 # -*- coding: utf-8 -*- from Tkinter import * import Image, ImageTk import test2 root = Tk() root.wm_title("InterActMap") def get(): global CountryName CountryName = e1.get() g

为了brevitys的缘故,这里留下了一些if,但在一些不同的战斗中也是一样的,命名按钮a、b、c、d、e、f等等

# -*- coding: utf-8 -*-
from Tkinter import *
import Image, ImageTk
import test2

root = Tk()
root.wm_title("InterActMap")

def get():


    global CountryName
    CountryName = e1.get()
    global Day
    Day = e2.get()
    global Month
    Month = e3.get()
    global Year
    Year = e4.get()
    Monthint=int(Month)
    Dayint=int(Day)
    Yearint=int(Year)

    if CountryName == "germany" and Monthint == 8 and Dayint == 26 and Yearint == 1914:
    global a
        a = Button(root, bg = "red", text ="Battle of Tannenberg" , command=None)
        a.place(x=691, y=229)
        test2.register(a, Tannenberg)
我知道问题是,当我单击“清除”时,所有按钮都不一定存在,因此它会抛出一个错误

def forget():
    a.place_forget()
    b.place_forget()
    c.place_forget()
    d.place_forget()
    f.place_forget()


canvas = Canvas(root, width = 1280, height=720)

country = Label(root, text = "Country")
country.place(x=5, y=5)
e1 = Entry(root)
e1.place(x=60,y=5)

day = Label(root, text = "Day")
day.place(x=230, y=5)
e2 = Entry(root)
e2.place(x=260, y=5)

month = Label(root, text = "Month")
month.place(x=430, y=5)
e3 = Entry(root)
e3.place(x=475, y=5)

year = Label(root, text = "Year")
year.place(x=645, y=5)
e4 = Entry(root)
e4.place(x=680, y=5)



File = "map1.jpg"
img = ImageTk.PhotoImage(Image.open(File))
canvas.create_image(0,0,image=img,anchor="nw")

Button1 = Button(root, text = "Submit", command=get)
Button1.place(x=850, y=5)
Button2 = Button(root, text = "Clear", command=forget)
Button2.place(x=925, y=5)
Button3 = Button(root, text = "Exit", command=root.quit)
Button3.place(x=960, y=5)




canvas.pack()
root.mainloop()
然后,忘记()中未定义的按钮之后的任何按钮都不会被清除

在研究了类似的问题之后,我发现将变量定义为某种东西,这样即使所有的if语句都不是真的,并且没有创建所有的按钮,变量至少也有一个值。那不管用,我只会

NameError: global name 'c' is not defined
我想出了一个解决办法,但这不是我真正想要的

AttributeError: 'NoneType' object has no attribute 'forget'
当我在地图上有多个按钮/战斗时,如果我只点击其中任何一个按钮/战斗,就会清除地图。抛出相同的错误,但至少清除了映射。
我已经试着让这项工作成功了,但我正在竭尽全力,谢谢你的帮助

因此在本例中可以使用
try/except
处理程序。小例子:

if CountryName == "germany" and Monthint == 8 and Dayint == 26 and Yearint == 1914:
    global a
        a = Button(root, bg = "red", text ="Battle of Tannenberg" , command=forget)
        a.place(x=691, y=229)
        test2.register(a, Tannenberg)
在这里,代码将返回一个
namererror
,因为
b
c
d
等不存在。然后异常会处理此问题,因此不会中断您的操作


希望对你有帮助

最好是创建一个实例级列表,其中包含所有按钮。例如:

from tkinter import *

root = Tk()

def forget()
    for x in (a, b, c, d, e, f, g):
        try:
            x.place_forget()
        except NameError:
            pass

a = Button(text = 'hi', command = forget)
a.place(x = 0, y = 0)

root.mainloop()
然后,您的忘记命令应该类似于:

button_list = []

if CountryName == "germany" and Monthint == 8 and Dayint == 26 and Yearint == 1914:
    a = Button(root, bg = "red", text ="Battle of Tannenberg" , command=None)
    a.place(x=691, y=229)
    button_list.append(a)
您的清除按钮应该如下所示:

def forget(lst_to_clear):
    for button in reversed(lst_to_clear):
        button.place_forget()
        lst_to_clear.pop()
        # the reversal is to make sure popping the item out of the
        # original list doesn't break the for loop. You could just
        # as easily do:
        # # while lst_to_clear:
        # #     lst_to_clear.pop().place_forget()
        # but I find it a little less readable.

为什么要尝试对可能绑定或不绑定到名称的对象调用方法?能否修复代码块中的
global a
缩进问题是异常实际上只应用于异常行为。我们希望不是所有这些按钮都会存在,所以我们不应该使用异常来处理它。@AdamSmith如果异常用于异常行为,并且它会给出一个
namererror
,否则,根据您的逻辑使用
try/except
(似乎您自相矛盾)。它确实起作用并解决问题,那么问题是什么呢?我想说,您的解决方案可能更为优雅。如果提示请求数字的用户输入失败,那将是一个例外。我们清理一张空间未完全填满的地图也不例外。事实上,只有当映射已满时才按下“清除”按钮的可能性很小。@AdamSmith它写道
namererror
可以使用异常处理程序修复。我的解决方案将采用任何存在的变量并将其忘记,其他变量将抛出异常处理的
namererror
,那么为什么这对您来说是个问题?@AdamSmith我认为您混淆了我答案的第一部分和第二部分,第一部分只处理一个变量,第二部分处理所有变量,如果它们不存在,例外情况会处理它。我将尝试编辑并澄清我的答案。请记住,您分配给
按钮的
命令
lambda是否有参数?我想这是鼠标点击事件,但现在我不记得了。您可能需要设置
按钮(root,text=“Clear”,command=lambda evt:forget(按钮列表))
Button2 = Button(root, text = "Clear", command=lambda: forget(button_list))
Button2.place(x=925, y=5)