ttk optionmenu小部件从下拉列表中的所有值开始。选择任何值后,列表中的第一个值将消失,永远不会重新出现...
有谁知道为什么?这是小部件设计的一个特征吗?尝试使用以下内容:
import tkinter.ttk as ttk
import tkinter as tk
a = tk.Tk()
options = ['1', '2', '3']
value = tk.StringVar()
masterframe = ttk.Frame()
masterframe.pack()
dropdown = ttk.OptionMenu(masterframe, value, *options)
dropdown.pack()
a.mainloop()
注意 - 其他用户在此处提出了相同的问题:OptionMenu won't show the first option when clicked (Tkinter)
他们似乎找到了一种解决方法,但不明白为什么会发生这种情况。
更新:实际上只有在使用ttk小部件时才会出现此行为。 tk小部件工作正常(尽管看起来非常难看)。
答案 0 :(得分:25)
ttk.OptionMenu命令的签名是:
def __init__(self, master, variable, default=None, *values, **kwargs):
这是docstring:
"""构建一个主人的OptionMenu小部件,以master作为父级, 资源textvariable设置为变量,最初选择的值 由默认参数指定,菜单值由 *值和其他关键字。
请注意值列表前面的default
选项。不是将空白项添加到值列表中,而是添加您想要的任何值作为默认值:
options = ['1', '2', '3']
dropdown = ttk.OptionMenu(masterframe, value, options[1], *options)
答案 1 :(得分:1)
似乎对于ttk.OptionMenu
,选项列表中的第一个条目必须留空:
import tkinter.ttk as ttk
import tkinter as tk
a = tk.Tk()
options = ['', '1', '2', '3']
value = tk.StringVar()
value.set(options[1])
masterframe = ttk.Frame()
masterframe.pack()
dropdown = ttk.OptionMenu(masterframe, value, *options)
dropdown.pack()
a.mainloop()
来源:http://www.pyinmyeye.com/2012/08/tkinter-menubutton-demo.html
答案 2 :(得分:1)
只是增加了其他人的答案,因为他们对我不起作用。我发现,如果您未在StringVar / IntVar中设置小部件选项,则不会显示已设置的标准值。这似乎很愚蠢,但花了我很多时间才能解决。希望能有所帮助,再见。 示例:
master = tk.Tk()
var = tk.StringVar(master)
master.mainloop()
答案 3 :(得分:0)
我在另一篇文章中也有同样的问题。我实际上已经阅读了这篇文章和答案,但是没有了解这两个选项菜单之间的细微差别。因此,即使我不熟悉Python和tkinter,这也是我的答案。
正如@Bryan Oakley回答的那样,是的,文档字符串显示,使用ttk.OptionMenu而不是tk.OptionMenu时,存在一个“附加”必需参数。如果您不愿意将声明从ttk.OptionMenu更改回tk.OptionMenu,则此区别将破坏(或至少弄乱)您的菜单。这是因为tk.OptionMenu不需要声明“默认”选项。如果出于某种原因将ttk.OptionMenu更改回tk.OptionMenu,并在声明中保留“ default”参数,它将复制OptionMenu中的第一个选项。我在墙上打了个头,弄清楚了为什么这两个行为不完全相同。我个人认为情况并非如此。如果有的话,“默认”参数应该是tk.OptionMenu和ttk.OptionMenu中的关键字,以实现兼容性。也许我错了,但这是我目前的看法。
要对此进行演示,请参见以下代码:
# test-optionmenu.py
import tkinter as tk
from tkinter import ttk
root = tk.Tk()
# tk OptionMenu lists
optionList1 = ('a', 'b', 'c')
optionList2 = ('d', 'e', 'f')
optionList3 = ('g', 'h', 'j')
# ttk OptionMenu lists
optionList4 = ('1', '2', '3')
optionList5 = ('4', '5', '6')
optionList6 = ('7', '8', '9')
optionList7 = ('z', 'x', 'y')
# Set up the StringVars for each OptionMenu
v1 = tk.StringVar()
v2 = tk.StringVar()
v3 = tk.StringVar()
v4 = tk.StringVar()
v5 = tk.StringVar()
v6 = tk.StringVar()
v7 = tk.StringVar()
# tk.OptionMenu requires the default option
# to be declared via the set() method.
v2.set(optionList2[1]) # Default tk.OptionMenu value for om2
v3.set(optionList3[2]) # Default tk.OptionMenu item value for om3
v5.set(optionList5[1]) # Default ttk.OptionMenu item value for om5
# -------------------------------------------
# tk OptionMenu om1 does not automatically
# assign a default based on your list, so
# this does not display a list item initially
om1 = tk.OptionMenu(root, v1, *optionList1)
# -------------------------------------------
# om2 demonstrates the 'default' parameter
# from a former ttk.OptionMenu is ignored by
# tk.OptionMenu because it needs to have the
# default list item set via v2.set() call.
# Notice the 'e' is displayed initially as
# set, but now 'd' is duplicated in the list
# as a remnant of the former ttk.OptionMenu
# 'default' parameter.
om2 = tk.OptionMenu(root, v2, optionList2[0], *optionList2)
# -------------------------------------------
# om3 is a tk.OptionMenu and has no 'default'
# paramter declared like om2 above does. Its
# default is set to option 2, or 'j', and is
# initially displayed on the dropdown. None
# of the OptionMenu list items are duplicated.
om3 = tk.OptionMenu(root, v3, *optionList3)
# -------------------------------------------
# om4 shows how the 'default' parameter
# from a former ttk.OptionMenu is ignored by
# tk.OptionMenu because it needs to have the
# default list item set via v4.set() call.
# Since v4 is not set, nothing at all is
# diplayed initially and when the OptionMenu
# is clicked, it will show that '1' is listed
# twice.
om4 = tk.OptionMenu(root, v4, optionList4[0], *optionList4)
# -------------------------------------------
# by changing a tk.OptionMenu to a
# ttk.OptionMenu, without properly declaring
# the default OptionMenu item in the ttk way
# will result in item '5' not being displayed
# initially, and '4' will not be displayed in
# the OptionMenu choices after a choice has
# been made.
om5 = ttk.OptionMenu(root, v5, *optionList5)
# -------------------------------------------
# om6 is the same as om5, except it does not
# have a tk.OptionMenu default declared. It
# is only here for consiceness.
om6 = ttk.OptionMenu(root, v6, *optionList6)
# -------------------------------------------
# om7 is the proper way to declare a
# ttk.OptionMenu, with a default option
# initially set.
om7 = ttk.OptionMenu(root, v7, optionList7[2], *optionList7)
# Pack'em all up
om1.pack()
om2.pack()
om3.pack()
om4.pack()
om5.pack()
om6.pack()
om7.pack()
# Execute the mainloop
root.mainloop()
我知道某些代码可能很丑陋,如果您真的要更改它,请继续。 :)
答案 4 :(得分:0)
旧帖子,但我认为我会添加到此对话中。在使用tk.OptionMenu
时,在Mac上默认显示第一个(或与此相关的列表中的任何项目)的一种非常简单的方法是利用tk.StringVar
例如:
options = ['option1', 'option2', 'option3', 'option4']
root = Tk()
var = StringVar()
var.set(options[0])
OptionMenu(root, var, *options)
mainloop()
selected = var.get()
使用var.set
来确定“设置”值是至关重要的。
希望有帮助!