nameerror:tkinter中未定义全局名称

时间:2014-11-20 22:15:11

标签: python tkinter

# -*- 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)

为了简洁起见留下了一些if if,但是在一些不同的战斗中也是如此,命名按钮a,b,c,d,e,f等。

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()

我知道问题是,当我点击清除时,所有按钮都不一定存在,所以它会抛出错误......

NameError: global name 'c' is not defined

然后,在未定义的那个按钮之后的任何按钮都不会被清除。

在查看类似问题之后,我看到将变量定义为某种东西,这样即使所有if语句都不正确且所有按钮都没有创建,变量至少也有一个值。这没有用,我只会得到

AttributeError: 'NoneType' object has no attribute 'forget'

我想出了一个解决方法,但它并不是我想要的

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)

有了这个,当我在地图上有多个按钮/战斗时,如果我只是点击其中任何一个,它就会清除地图。抛出相同的错误,但至少清除了地图。 我试着做这个工作,但是我把头发拉了出来,感谢任何帮助!

2 个答案:

答案 0 :(得分:2)

最好的办法是创建一个包含所有按钮的实例级列表。例如:

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.

并且您的清晰按钮应如下所示:

Button2 = Button(root, text = "Clear", command=lambda: forget(button_list))
Button2.place(x=925, y=5)

答案 1 :(得分:1)

所以你可以在这种情况下使用try/except处理程序。小例子:

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()

此处代码将返回NameError,因为bcd等不存在。此例外处理此问题,因此您不是' t打断了。

希望能帮到你!