删除/销毁在for循环中创建的python 3.4上的按钮

时间:2014-12-27 01:31:51

标签: python for-loop tkinter widget python-3.3

我试图销毁我在for循环中点击的按钮。尝试使按钮进入列表,然后使用列表删除,但我似乎无法使其工作。

以下是代码:

root = Tk()

word_list = ["APPLE", "PEAR", "BANANA"]

word = word_list [random.randint(0,2)]

abc = '_ ' * len(word)
print (word)
lives = 0

guessed_letters = []

buttons = []

#Function
def click_1 (key):
    buttons.append(key)
    print (buttons)
    if key in word:
        guessed_letters.append(key)
        abc = ''.join([key if key in guessed_letters else "_ " for key in word])
        if abc == word:
            letters_label.config(text="You win!")
            raise SystemExit
        letters_label.config(text=abc)
        key_1 = buttons.index(key)
        buttons[key_1].destroy(END)
    else:
        guessed_letters.append(key)
        global lives
        lives += 1
        hangman_label.config(text=hangman_pics[lives])
        if lives == 6:
            letters_label.config(text="You lose...")
            lives -= 1
            raise SystemExit





#Frames
hangman_frame = Frame(root)
hangman_frame.grid(row=0, column=0, sticky=N)
letter_frame = Frame(root)
letter_frame.grid(row=1, column=0, sticky=S)

#Label
letters_label = Label(hangman_frame, text=abc)
letters_label.grid(row=0, column=0, sticky=W)

hangman_label = Label(hangman_frame, text=hangman_pics[lives])
hangman_label.grid(row=1, column=0, sticky=W)



#Buttons
r = c = 0
for letter in string.ascii_uppercase:
    Button(letter_frame, text=letter, command=functools.partial(click_1, letter)).grid(row=r, column=c, sticky=W)
    c += 1
    if c > 12:
        c = 0
        r += 1

(对不起,认为一切都是相关的)

任何人都可以看到任何错误吗?我尝试过很多不同的东西,但都不起作用。此代码的特定错误消息是:

['A']
Exception in Tkinter callback
Traceback (most recent call last):
  File "/Library/Frameworks/Python.framework/Versions/3.3/lib/python3.3/tkinter/__init__.py", line 1475, in __call__
    return self.func(*args)
  File "/Users/alexeacott/Desktop/Hangman.py", line 85, in click_1
    buttons[key_1].destroy(END)
AttributeError: 'str' object has no attribute 'destroy'

如果我改变了     。破坏() 至 .grid.forget 错误说:

AttributeError: 'str object has no attribute 'grid' 

我怎么能不把它变成一个'?如何使我的代码正常工作?!

提前致谢。

修改

根据建议:

#Buttons
r = c = 0
for letter in string.ascii_uppercase:
    c += 1
    my_button = Button(letter_frame, text=letter).grid(row=r, column=c, sticky=W)
    my_button.configure(command=functools.partial(click_1, letter, my_button)
    if c > 12:
        c = 0
        r += 1

这表示该行的冒号有语法错误:

if c > 12:

1 个答案:

答案 0 :(得分:1)

在您创建按钮的语句中:

Button(letter_frame, text=letter, command=functools.partial(click_1, letter)).grid(row=r, column=c, sticky=W)

您将letter作为参数传递给click_1(key)letterstr。这就是问题所在。

您要做的是,将按钮本身作为另一个参数传递给它。只有在创建按钮后才能执行此操作,如下所示:

my_button = Button(letter_frame, text=letter)
my_button.configure(command=functools.partial(click_1, letter, my_button))
my_button.grid(row=r, column=c, sticky=W)

并修改click_1方法,将按钮作为其中的一个参数,如下所示:

#Function
def click_1 (key, button):
    buttons.append(button)
    # ...

<强> 更新

您可能需要修改click_1方法才能使用key获取按钮。您可以执行的一项简单更改是将buttons作为OrderedDict而不是列表。 OrderedDict只是一个dict,可以记住list之类的项目顺序。所以你修改过的方法看起来像是:

from collections import OrderedDict()
buttons = OrderedDict()        

#Function
def click_1 (key, button):
    buttons[key] = button
    print (buttons)
    if key in word:
        guessed_letters.append(key)
        abc = ''.join([key if key in guessed_letters else "_ " for key in word])
        if abc == word:
            letters_label.config(text="You win!")
            raise SystemExit
        letters_label.config(text=abc)
        #key_1 = buttons.index(key) # REMOVE this
        #buttons[key_1].destroy(END) # REMOVE this
        #Do this instead:
        buttons[key].destroy(END)
    else:
        guessed_letters.append(key)
        global lives
        lives += 1
        hangman_label.config(text=hangman_pics[lives])
        if lives == 6:
            letters_label.config(text="You lose...")
            lives -= 1
            raise SystemExit

希望这很有用。