单击时销毁按钮(销毁错误)

时间:2020-08-15 01:51:57

标签: python button tkinter

我有一个按钮网格。右键单击按钮后,目标是在该按钮的顶部创建一个新的按钮,上面带有标志图像。然后在左键单击后,我要销毁该新按钮。当前,单击鼠标右键的部分有效,但单击鼠标左键时出现错误“无法调用“销毁”命令:应用程序已被破坏”。我浏览了许多问题和答案,但无法弄清楚。

def flags():
    for i in range(0,324):
        buttonlist[i].bind("<Button-3>", globals()[rightlist[i]])

def copy_function(fn, name):
    return FunctionType(
    copy(fn.__code__),
    copy(fn.__globals__),
    name=name,
    argdefs=copy(fn.__defaults__),
    closure=copy(fn.__closure__))    

for i in range(1,325):
    name = 'right' + str(i)
    def _right(event):
        global flag1
        flaglist[i-1] = tk.Button(app, text = "", width=16, height=18, image = flag)
        flaglist[i-1].grid(row=rowlist[i-1], column=columnlist[i-1], columnspan=1)
        flaglist[i-1].bind("<Button-1>", globals()[leftlist[i-1]])
    globals()[name] = copy_function(_right, name)

for i in range(1,325):
    name = 'left' + str(i)
    def _left(event):
        flaglist[i-1].destroy()
    globals()[name] = copy_function(_left, name)

1 个答案:

答案 0 :(得分:0)

我认为您使用global()复制了所有代码,并复制了函数。

您可以使用lambda为函数分配参数。

因为在lambda循环中使用了for,所以它需要y=row,x=col才能将值复制到新变量中。没有这个,所有按钮将使用相同的值。


最少的工作代码。

我使用带有文本X的按钮代替图像-这样,每个人都可以测试它。

import tkinter as tk

# --- functions ---

def add_button(row, col):
    b = tk.Button(root, text=f' X ')
    b.grid(row=row, column=col)
    b.bind('<Button-3>', lambda event:b.destroy())
    
# --- main ---

root = tk.Tk()

for row in range(5):
    for col in range(5):
        b = tk.Button(root, text=f'{row},{col}')
        b.grid(row=row, column=col)
        b.bind('<Button-1>', lambda event, y=row,x=col:add_button(y,x))

root.mainloop()

其他方法是替换现有按钮中的配置,或者使用类tk.Button创建具有所有功能的新类,然后在网格中使用它。

import tkinter as tk

# --- classes ---

class MyButton(tk.Button):
    
    def __init__(self, master, row, col, *args, **kwargs):
        super().__init__(master, *args, *kwargs)
        
        self.left_text = f'{row},{col}'
        self.right_text = ' X '
        
        self.bind('<Button-1>', self.on_left_click)
        self.bind('<Button-3>', self.on_right_click)

        self['text'] = self.left_text
        self.state ='left'
        
    def on_left_click(self, event):
        if self.state == 'left':
            self.state = 'right'
            self['text'] = self.right_text
            
    def on_right_click(self, event):
        if self.state == 'right':
            self.state = 'left'
            self['text'] = self.left_text
        
# --- main ---

root = tk.Tk()

for row in range(5):
    for col in range(5):
        b = MyButton(root, row, col)
        b.grid(row=row, column=col)

root.mainloop()