简体   繁体   English

Python / Tkinter OptionMenu更新会创建菜单的“阴影”

[英]Python/Tkinter OptionMenu Update creates a “Shadow” of the Menu

So I'm still quite new to this (my code should make this obvious) and I am working on a GUI with tkinter. 因此,我对此还很陌生(我的代码应该使这一点很明显),并且我正在使用tkinter来开发GUI。 I am trying to have an OptionMenu which shows Keys from a dict and and upon clicking on a key I would like to see the value. 我试图有一个OptionMenu,它显示一个字典中的键,并且在单击一个键时,我想查看该值。 I want to modify that dict and would like to be able to update said OptionMenu. 我想修改该字典,并希望能够更新所说的OptionMenu。

So far, so good. 到现在为止还挺好。 Now I've been able to get this to "work" - but when I update the menu (after changing it or not) I get a shadow of the menu itself. 现在,我已经能够使它“工作”-但是,当我更新菜单(无论是否更改之后)时,我都会看到菜单本身的阴影。

I've conconcted a small test program: 我已经构建了一个小型测试程序:

import tkinter as tk
from tkinter import ttk

class MyApp():

    def __init__(self,master):

        self.master = master
        self.myDict =  {'Key1':1, 'Key2': 2, 'Key3':3}


        self.valueVar = tk.StringVar()
        self.valueVar.set("0.00")

        self.RCS = tk.Label(master, textvariable=self.valueVar).grid(row=5, column=3)

        updateButton = tk.Button(text= "Update List", command =  self.update)
        updateButton.grid(row=4,column=4)

        changeButton = tk.Button(text= "Change list", command =  self.changeDict)
        changeButton.grid(row=5,column=4)


        self.keyVar = tk.StringVar(master)

        self.om = ttk.OptionMenu(self.master, self.keyVar, "Select Key ", *self.myDict, command = self.setKey )
        self.om.configure(width=20)
        self.om.grid(row=4, column=3)

    def setKey(self,Surface):
        self.valueVar.set(self.myDict[Surface])

    def update(self):
        menu = self.om["menu"]
        menu.delete(0,"end")
        menu.destroy
        menu = ttk.OptionMenu(self.master, self.keyVar, "Select Key", *self.myDict, command = self.setKey )
        menu.grid(row=4, column=3)

    def changeDict(self):
        self.myDict =  {'Key4':4, 'Key5': 5, 'Key6':6}

root = tk.Tk()
app = MyApp(root)
root.mainloop()

What do I have to change? 我必须改变什么? Why? 为什么? Usually I work with Matlab. 通常我与Matlab合作。 I guess it shows. 我猜它显示了。

Much appreciated! 非常感激!

As far as I understand this mini-program you which for it to display an optionmenu with the keys of a dict and then when you press "change dict" and then update it should switch the optionmenu to the other set of items? 据我了解这个小程序,您为它显示了一个带有字典键的选项菜单,然后当您按“更改字典”然后进行更新时,应该将选项菜单切换到其他项目集吗? In this case, you were calling the destroy on the wrong widget. 在这种情况下,您在错误的小部件上调用了destroy。 The only issue was with the update function which should be changed to: 唯一的问题是更新功能,应将其更改为:

def update(self):
        #menu = self.om["menu"]
        #menu.delete(0,"end")
        #The above two menu items are not neede dif you are just going to destroy the widget
        self.om.destroy()
        self.om = ttk.OptionMenu(self.master, self.keyVar, "Select Key", *self.myDict, command = self.setKey )
        self.om.configure(width=20)
        self.om.grid(row=4, column=3)

This will do what I think you want it to do. 这将完成我认为您想要的操作。 Just so you know, the optionmenu widget is actually a combination of a button and a menu widget. 众所周知,optionmenu小部件实际上是按钮和菜单小部件的组合。 So when you do menu = self.om["menu"], you are actually getting the menu object of the optionmenu widget and then destroying that. 因此,当您执行menu = self.om [“ menu”]时,实际上是在获取optionmenu小部件的menu对象,然后销毁它。 Then you are replacing that variable with an optionmenu and losing the original menu whilst not destroying the original optionmenu (self.om). 然后,用选项菜单替换该变量,并丢失原始菜单,同时不破坏原始选项菜单(self.om)。 This is why you got the shadow. 这就是为什么你有阴影。 Some other notes though: 不过,还有一些其他注意事项:

  1. There is no need for the user to have to press 2 buttons when switching lists - call the update function from the changedict function so that it automatically populates. 切换列表时,用户无需按2个按钮-从changedict函数调用update函数,使其自动填充。
  2. You can iterate over the menu items as you began to do but you need to decide on one or the other. 您可以在开始时遍历菜单项,但是您需要决定一个或另一个。 I can't comment on the efficiency of completely destroying and enabling the widget or changing the menu items of the current widget as I am still rather experienced. 我无法完全销毁并启用小部件或更改当前小部件的菜单项的效率,因为我仍然相当有经验。

Hopefully that helps! 希望有帮助!

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

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