【问题标题】:tkinter how delete both checkbox and label if checked box如果选中复选框,tkinter 如何删除复选框和标签
【发布时间】:2021-12-21 18:31:06
【问题描述】:

我正在尝试选中一个复选框并使用上方按钮删除“复选框”和“标签”。它们都是从同一个列表中循环创建的。 我试图建立一个字典,以“按钮”为键,以“result_of_checkboxes”为值,如果值与“”不同,则销毁键。这是行不通的。如果按钮是钥匙,为什么我不能破坏它们?什么是正确的方法? 提前致谢!

from tkinter import *
    
root = Tk()    
root.geometry('400x400')
    
def destroy_button():
    for key, value in dict_check_and_buttons:
        if value != '' and current_var != '':
            key.destroy()      
            current_box.destroy()    

my_friends = ['Donald', 'Daisy', 'Uncle Scrooge']
    
button1= tk.Button(root, text = "delete both if cbox is checked", command = destroy_button).pack()
    
#-----ild checkbuttons and store results in checkbutton_result list

checkbutton_result = []

for index, friend in enumerate(my_friends):
    current_var = tk.StringVar()
    current_box = tk.Checkbutton(root, text= friend,
                                 variable = current_var,
                                 onvalue = friend, offvalue = ""
                                 )
    checkbutton_result.append(current_var) #append on and off results
    current_box.pack()
        
#-----build buttons and store them in buttons_list
buttons_list = []

for index, friend in enumerate(my_friends):
    buttons= tk.Button(root, text = friend).pack()
      
    buttons_list.append(buttons)
        
#-----build a dict with list to say "if  onvalue != '' destroy button"    

dict_check_and_buttons = dict(zip(buttons_list, checkbutton_result))   

root.mainloop()

 

错误是:

Exception in Tkinter callback
Traceback (most recent call last):
  File "c:\python\python38\lib\tkinter\__init__.py", line 1892, in __call__
    return self.func(*args)
  File "<ipython-input-18-954d3a090f2c>", line 7, in destroy_button
    for key, value in dict_check_and_buttons:
TypeError: cannot unpack non-iterable NoneType object

【问题讨论】:

  • 您的buttons_list 只是一个包含Nones 的列表——调用.pack() 的结果,而不是小部件本身。您需要单独执行 .pack(),就像您在 checkbutton_result 循环中所做的一样。

标签: python for-loop tkinter checkbox destroy


【解决方案1】:

您的代码存在以下问题:

  • buttons_list 中的所有项目都是 None 由于以下行
buttons= tk.Button(root, text = friend).pack()  # buttons is the result of pack()

该行应该分成两行:

buttons = tk.Button(root, text=friend)
buttons.pack()
  • 您无法通过迭代字典获得(键、值)对
for key, value in dict_check_and_buttons:  # dict_check_and_buttons is a dictionary
    ...

相反,您应该迭代 dict_check_and_buttons.items() 的结果:

for key, value in dict_check_and_buttons.items():
    ...
  • 您需要在tk.StringVar() 上致电get()
for key, value in dict_check_and_buttons.items():
    if value.get() != '':  # use value.get()
        key.destroy()

如果您还需要销毁检查按钮,则需要将检查按钮连同其关联变量一起保存到checkbutton_result

checkbutton_result = []

for index, friend in enumerate(my_friends):
    current_var = tk.StringVar()
    current_box = tk.Checkbutton(root, text= friend,
                                 variable = current_var,
                                 onvalue = friend, offvalue = ""
                                 )
    checkbutton_result.append((current_box, current_var)) # save both checkbutton and its associated variable
    current_box.pack()

然后销毁destroy_button()里面的checkbutton:

def destroy_button():
    for btn, (cb, cbvar) in dict_check_and_buttons.items():
        if cbvar.get() != '':
            btn.destroy()
            cb.destroy()

【讨论】:

  • 尊敬的ACW1668先生非常感谢您,这些对我来说是新的相关概念。
【解决方案2】:

根据您的回答,我重建了代码。多亏了你,现在完美了。

import tkinter as tk

root = tk.Tk()
root.geometry('400x400')
'''
to get if checkbox is checked to use results to delete checkbox and label
'''


def destroy_button_box():
    for button_names, (ckbox, on_off) in dict_buttons_box_var.items():
        if on_off.get() != 0:
            button_names.destroy()
            ckbox.destroy()
        


my_friends = ['Donald', 'Daisy', 'Uncle Scrooge']

button1 = tk.Button(root, text="delete label if box is checked", command=destroy_button_box).pack()


checkbox_variable_list = []

box_list = []

for index, friend in enumerate(my_friends):
    #     current_var = tk.IntVar()
    current_var = tk.IntVar()
    #   current_var = tk.StringVar()
    current_box = tk.Checkbutton(root, text=friend,
                                 variable=current_var,
                                 onvalue=1, offvalue=0
                                 )

    current_box.pack()
    
    # append checkbox and 'on' or 'off' results
    checkbox_variable_list.append((current_box, current_var))

# -----build buttons and store them in buttons_list
buttons_list = []
for index, friend in enumerate(my_friends):
    button_names = tk.Button(root, text=friend)
    button_names.pack()
    
    # append buttons in loop
    buttons_list.append(button_names)

# -----build a dict with lists to use in destroy_box_button function:
dict_buttons_box_var = dict(zip(buttons_list, checkbox_variable_list))

root.mainloop()

【讨论】:

  • 两者在同一个功能中更好,再次感谢。 btn.destroy() cb.destroy() and (cb, cbvar) 精彩纷呈!
猜你喜欢
  • 1970-01-01
  • 2019-09-23
  • 1970-01-01
  • 2011-12-22
  • 1970-01-01
  • 2021-12-24
  • 2014-01-01
  • 2013-12-06
  • 2016-06-29
相关资源
最近更新 更多