【问题标题】:Destroying a widget if another selection is made in an OptionMenu如果在 OptionMenu 中进行了另一个选择,则销毁小部件
【发布时间】:2021-09-01 08:48:44
【问题描述】:

我正在使用 tkinter 制作 GUI。我希望某些小部件仅在选择某些参数时出现。我为此使用了 .pack_forget() 方法。但是,现在我有另一个问题。我在 OptionMenu 上设置了一个条件,根据用户的选择,它会显示为 ComboBox 还是 Entry。但是如果用户改变他的选择,我无法设法让这两个小部件中的一个消失。

这是我的代码:

# Creation of Frame 4 #

Frame4 = tk.Frame(fenetre)
Frame4.pack(anchor = tk.NW, padx = 5, pady = 5)

# label4 creation #

label4 = tk.Label(Frame4, text = "what is the format?", font = ('Arial', '12'))
label4.pack(side = tk.LEFT)

# Création de la commande #

def Format_choice(self):

   global Format

   if choice.get() != Format:
      Format = choice.get()
    
   if Format == "CAPS Client":
    
      # Création de la liste déroulante
      Frame6.pack(anchor = tk.NW, padx = 5, pady = 5)

      # NOMS is a list of strings
      comboExample = ttk.Combobox(Frame6, textvariable = tk.StringVar(), values = NOMS, width = 45)
                    
      comboExample.current(0)

      def callbackFunc(self):
          global nom_site
          nom_site = comboExample.get()

      comboExample.bind("<<ComboboxSelected>>", callbackFunc)

      comboExample.pack(side = tk.LEFT)


   elif Format == "ETUDE":
        
      Frame6.pack(anchor = tk.NW, padx = 5, pady = 5)
        
      site = tk.StringVar()

      def Name():

         global nom_site
         nom_site = site.get()


      entrysite = tk.Entry(Frame6, textvariable = site)
      entrysite.pack(side=tk.LEFT, padx=5, pady=5)
      entrysite.focus_set()
        
      valider = tk.Button(Frame6, text="Confirmer", command = Name, activeforeground = 'red')
      valider.pack(side = tk.LEFT)
    

# Creation of choice#      
    
choice = tk.StringVar()
choice.set("Default")


# Creation of the OptionMenu #

option4 = tk.OptionMenu(Frame4, choice, "Format1", "Format2", command = Format_choice)
option4.pack(side = tk.LEFT)

# Creation of Frame6 

Frame6 = tk.Frame(fenetre)

# label6 creation

label6 = tk.Label(Frame6, text= "What is the name of the site ?", font = ('Arial', '12'))

label6.pack(side=tk.LEFT)

Frame6.pack_forget()

【问题讨论】:

  • 你能用更好的变量名吗?现在您有一个名为FORMAT 的变量和另一个名为Format 的变量。此外,您还有一个未真正使用的变量 site。也不建议使用嵌套函数。也请看PEP 8
  • “但是,如果用户改变他的选择,我无法设法让两个小部件中的一个消失。” 为什么你不能呢?当你尝试时会发生什么?
  • @TheLizzard 是的,我同意目前还不清楚我要解决这个问题
  • @BryanOakley 当我尝试时,如果我选择“Format1”,则会创建一个组合框,但如果我改变主意并选择“Format2”,则会在组合框旁边创建一个条目。
  • 我尝试在各个循环的开头使用 ComboExample.destroy() 或 entrysite.destroy() 但如果它们不存在,则它不起作用。也尝试过,使用带有 winfo_exists() 的条件

标签: python tkinter tkinter-menu


【解决方案1】:

pack_forget() 只会使 Frame6 在这里不可见,而它仍然在那里。 因此,请改用.destroy()。在这里得到了很好的回答:

Python Tkinter clearing a frame

所以,基本上你有两个选择:

  1. 销毁 Frame6 并在每个 if-elif 函数 Format_choice() 的情况下再次创建其中的所有内容,或者
  2. 销毁由先前选择的选项创建的Frame6 的每个小部件。

如果您喜欢第二种方式,可以在 if-elif 案例之前添加一段代码。使用winfo_children() 就像一个魅力:

.
.
def Format_choice(self):
   global Format

   if choice.get() == Format:
      return   #so that if user selects same option again, no change occurs in Frame6
   else:
      Format = choice.get()

   for widget in Frame6.winfo_children():
        if widget != label6:
            widget.destroy()
            
   if Format == "CAPS Client":
      # Création de...
   .
   .
   .

这样,您可能不想销毁的label6 不会被销毁,而其他小部件会被销毁。

【讨论】:

  • 我要指出的一点是,您的 OptionMenu 有“Format1”和“Format2”选项,但您的函数使用值“CAPS Client”和“ETUDE”作为条件,所以我希望您能清楚就这样。
  • 非常感谢,它完全按照我想要的方式工作!我清除它是的!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-12-14
  • 1970-01-01
  • 2011-07-24
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多