2014-11-20 103 views
1
# -*- 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) 

留下了几个,如果这里出去brevitys缘故,而是与几个不同的战役同样的事情,命名按钮A,B,C,d,E,F等。nameerror:全局名称不Tkinter的定义

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) 

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

+0

为什么你试图调用一个方法上可能会或可能不会被绑定到名称的对象? – 2014-11-20 22:19:29

+0

你能在代码块中修复'global a'的缩进吗请 – W1ll1amvl 2014-11-20 22:31:57

回答

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. 

和您的Clear按钮应该是这样的:

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

任何人都记得如果你分配给'Button'的'command'的'lambda'有参数吗?我想这是给鼠标点击事件,但现在我不记得了。有可能你必须做这个'Button(root,text =“Clear”,command = lambda evt:forget(button_list))' – 2014-11-20 22:57:57

+0

它没有这个工作,谢谢! – kodiak3 2014-11-21 15:20:54

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等,不要再exist.The异常与此交易,这样你就不会中断。

希望能帮到你!

+1

这个问题是,异常只能用于特殊的行为。我们预计并不是所有这些按钮都会存在,所以我们不应该使用异常来处理它。 – 2014-11-20 22:56:33

+0

@AdamSmith如果异常将用于例外行为,并且它会给出一个'NameError',否则在你的逻辑中使用'try/except'是很有意义的(看起来好像你自相矛盾)。它确实有效并解决了问题,那么问题是什么?我想说,你的解决方案可能更优雅。 – W1ll1amvl 2014-11-20 23:07:17

+0

用户输入的提示请求一个数字失败“int”将是例外。我们清除空间不完整的地图并不是特例。事实上,只有在地图已满时才按下“清除”按钮的可能性非常小。 – 2014-11-20 23:13:18

相关问题