首页 > 解决方案 > 单击时销毁按钮(销毁错误)

问题描述

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

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)

标签: pythonbuttontkinter

解决方案


global()我认为您使用和复制功能使所有代码过于复杂。

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

因为lambdafor-loop 中使用,所以它需要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()

推荐阅读