简体   繁体   English

tkinter:为什么 Combobox 和 Entry 小部件没有被 delete("all") 删除?

[英]tkinter: Why aren't Combobox and Entry widgets deleted by delete("all")?

I mean the whole widget not the text inside.我的意思是整个小部件而不是里面的文字。 I also tried to get an existing solution on the forum.我还尝试在论坛上获得现有解决方案。 I have stripped code to show the problem only.我已经剥离了代码以仅显示问题。

My problem is... When I place ComboBox and Entry widgets on canvas2 , they don't get deleted with a canvas2.delete("all") .我的问题是......当我将ComboBoxEntry小部件放在canvas2上时,它们不会被canvas2.delete("all")删除。

The problem happens if you select "Weighted Graph", then "Undirected Graph" from the menu.如果您 select “加权图”,然后从菜单中选择“无向图”,就会出现问题。 After "Weighted Graph", the ComboBox and Entry widgets remain (everything else gets deleted as expected).在“加权图”之后, ComboBoxEntry小部件仍然存在(其他所有内容都按预期删除)。 I put in a time delay and some prompts to show the problem.我设置了时间延迟和一些提示来显示问题。

from tkinter import *
from tkinter import ttk
import time

tk = Tk()
tk.geometry("970x660")
menubar = Menu(tk)
tk.config(menu=menubar)

wrapper1 = LabelFrame(tk, text="Display", height=500)
wrapper2 = LabelFrame(tk, text="Command", width=800)

# canvas was setup to be a vertically scrolling region, I have cut most of that code
# (but my problem does not lie with canvas, that's working fine)
canvas = Canvas(wrapper1, height=500)
canvas.pack(side=LEFT, fill="both", expand="yes")

myframe = Frame(canvas)
canvas.create_window((0,0), window=myframe, anchor="nw", height=500)

# Note: My problem lies on canvas2,
canvas2 = Canvas(wrapper2)
canvas2.pack(side=LEFT, fill="both", expand="yes")

canvas2.update()

wrapper1.pack(fill="both", expand="yes", padx=10, pady=0)
wrapper2.pack(fill="both", expand="yes", padx=10, pady=5)

def DoNothing():
    print("Doing nothing!")

def BinaryTree(Weighted, Mode):

    canvas.delete("all")
    print("Before canvas2.delete...")
    canvas2.delete("all")
    print("...after canvas2.delete... now waiting 3 seconds so you can inspect if canvas2 is CLEAR... ")
    print("...I would expect canvas2 to be clear but Combobox and Entry remain!... ")

    canvas2.update()
    tk.update()

    time.sleep(3)

    button1 = Button(canvas2, text = "Add Node",  command= lambda: DoNothing(), width=13, anchor=W)
    button1_window = canvas2.create_window(20, 40, anchor=W, window=button1)

    entry1 = Entry(canvas2, width=10)
    entry1.place(x=150, y=40, anchor=W)

    button2 = Button(canvas2, text = "Add Edge",  command= lambda: DoNothing(), width=13, anchor=W)
    button2_window = canvas2.create_window(20, 80, anchor=W, window=button2)

    cb1 = ttk.Combobox(canvas2, values=DoNothing(), postcommand=lambda: DoNothing(), width=13, state="readonly")
    cb1.place(x=150, y=80, anchor=W)

    cb2 = ttk.Combobox(canvas2, values=DoNothing(), postcommand=lambda: DoNothing(), width=13, state="readonly")
    cb2.place(x=260, y=80, anchor=W)

    if Weighted == True:
        canvas2.create_text(380, 80, text="Weight:", anchor=W)
        entry2 = Entry(canvas2, width=4)
        entry2.place(x=429, y=80, anchor=W)

    button3 = Button(canvas2, text = "Delete All Nodes",  command= lambda: DoNothing(), width=13, anchor=W)
    button3_window = canvas2.create_window(420, 40, anchor=W, window=button3)

    canvas2.update()
    tk.update()

lmenu = Menu(menubar)
menubar.add_cascade(label="Learning Menu", menu=lmenu)

lmenu.add_command(label="Weighted Graph", command= lambda: BinaryTree(True, "DirectedGraph"))
lmenu.add_command(label="Undirected Graph", command= lambda: BinaryTree(False, "UndirectedGraph"))


while True:
    tk.update_idletasks()
    tk.update()
    time.sleep(0.01)

Why aren't Combobox and Entry widgets deleted by delete(“all”)?为什么 Combobox 和 Entry 小部件没有被 delete(“all”) 删除?

That's just how tkinter is designed to work.这就是 tkinter 设计的工作原理。 The canvas delete method only deletes canvas objects. canvas delete方法只删除了canvas个对象。 That means, objects created on the canvas with the "create" functions ( create_rectangle , create_window , etc).这意味着,在 canvas 上使用“创建”函数( create_rectanglecreate_window等)创建的对象。 For window objects, the delete method will delete the canvas object created with create_window but it's not designed to delete the widget associated with that window object.对于 window 对象, delete方法将删除使用 create_window 创建的create_window object,但它并不是为了删除与 window object 关联的小部件。

Like with any widget, to delete the actual widget you need to call the destroy method on the widget itself.与任何小部件一样,要删除实际的小部件,您需要调用小部件本身的destroy方法。

My problem is... When I place ComboBox and Entry widgets on canvas2, they don't get deleted with a canvas2.delete("all").我的问题是...当我将 ComboBox 和 Entry 小部件放在 canvas2 上时,它们不会被 canvas2.delete("all") 删除。

That is because when you use place , you are not creating canvas objects.那是因为当您使用place时,您并没有创建 canvas 个对象。 For the delete command to work, you must call create_window for the combox and entry widgets.要使delete命令起作用,您必须为组合框和条目小部件调用create_window

To destroy a widget in tkinter try.destroy()销毁 tkinter 中的小部件 try.destroy()

f1=tk.Frame()
f1.destroy()

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM