【问题标题】:Tkinter Widget won't disappear even if I use destroy/pack_forget即使我使用destroy/pack_forget,Tkinter Widget 也不会消失
【发布时间】:2018-10-02 18:26:48
【问题描述】:

我正在学习 GUI,作为测试,我正在尝试开发一个带有两个单选按钮的框架,一个用于随机模拟,一个用于文件输入模拟。当我想要文件输入模拟时,需要文件名,所以我的第二个单选按钮通过 switch_entry 命令打包新的标签/条目。如果第一个单选按钮被选中,调用的方法也应该删除标签和条目。

我尝试了 pack_forget 和销毁,但结果是我通过选择第二个单选按钮来创建 de 标签/条目,但不能通过选择第一个单选按钮来销毁它们。当我交替选择第一个和第二个单选按钮时,GUI 会不断添加标签/条目集。代码和图片如下:

import tkinter as tk


class InterRiver(tk.Frame):

    def __init__(self, master = None):
        self.mode = tk.StringVar(value="Random")
        tk.Frame.__init__(self, master)
        self.lblChooseMode = tk.Label(self, text="Opções do Simulador").pack(side="top")
        self.rdModeRndm = tk.Radiobutton(self, text = "Rio Aleatório", value = "Random", variable = self.mode,
                                         command = self.switch_entry).pack(anchor="w", side="top")
        self.rdModeFile = tk.Radiobutton(self, text = "Rio a partir de arquivo", value= "File", variable = self.mode,
                                         command = self.switch_entry).pack(anchor ="w", side="top")
        self.btnStart= tk.Button(self, text = "Simular", command = simular).pack(side = "bottom")
        self.lblCycles = tk.Label(self, text = "Número de Ciclos").pack(side="top")
        self.ntyCycles = tk.Entry(self).pack(side="top")
    def switch_entry(self):
        lblFile = tk.Label(self, text="Insira o nome do arquivo")
        ntyFile = tk.Entry(self)
        if self.mode.get() == "File":
           lblFile.pack(side="top")
           ntyFile.pack(side="top")
        else:
           lblFile.destroy()
           ntyFile.destroy()
if __name__ == "__main__":
    w = tk.Tk()
    InterRiver(w).pack()
    w.title("Bears and Fishes")
    w.mainloop()

【问题讨论】:

    标签: python user-interface tkinter radio-button


    【解决方案1】:

    当你销毁时,你试图销毁你没有打包的东西,因为你在switch_entry的开头创建了它,然后要么打包它,要么销毁它。你的switch_entry 函数应该是:

        if self.mode.get() == "File":
           self.lblFile = tk.Label(self, text="Insira o nome do arquivo")
           self.ntyFile = tk.Entry(self)
           self.lblFile.pack(side="top")
           self.ntyFile.pack(side="top")
        else:
           self.lblFile.destroy()
           self.ntyFile.destroy()
    

    实际上,更快的方法是将这些行放入__init__

           self.lblFile = tk.Label(self, text="Insira o nome do arquivo")
           self.ntyFile = tk.Entry(self)
    

    然后在switch_entry:

        if self.mode.get() == "File":
           self.lblFile.pack(side="top")
           self.ntyFile.pack(side="top")
        else:
           self.lblFile.pack_forget()
           self.ntyFile.pack_forget()
    

    【讨论】:

    • 另外,我很确定,除了删除和重新打包小部件之外,我认为您可以打包不同框架的不同对象并使用lift()
    • 我试过了,但是当我选择第一个单选按钮触发 switch_entry 时,我收到了这个错误:Tkinter 回调 Traceback 中的异常(最近一次调用最后一次):(...)第 25 行,在 switch_entry lblFile.destroy() UnboundLocalError: local variable 'lblFile' referenced before assignment
    • @Suri 尝试了 Pygasm 的建议还是我的回答?
    • init 中创建小部件确实有效!感谢@Artemis Fowl 和 Pygasm 的回答。我一有时间就研究一下lift()的用法,因为我很着急完成这个项目。非常感谢。
    • 然而,我真的不明白为什么它会在____init____中工作,但不能在方法中工作。也许随着时间的推移我会做......
    猜你喜欢
    • 2019-08-03
    • 2023-01-28
    • 1970-01-01
    • 1970-01-01
    • 2014-01-13
    • 1970-01-01
    • 1970-01-01
    • 2021-03-13
    • 1970-01-01
    相关资源
    最近更新 更多