有关 tkinter optionmenu 第一个选项消失的更多信息

2024-02-25

这是我的问题的后续here https://stackoverflow.com/questions/25194969/more-on-python-tkinter-dynamic-optionmenu/25196500#25196500。我正在尝试使用 ttk.OptionMenu 来增强下拉菜单的外观和感觉。但正如帖子中指出的here https://stackoverflow.com/questions/19138534/tkinter-optionmenu-first-option-vanishes,“ttk optionmenu 小部件以下拉列表中的所有值开始。选择任何值后,列表中的第一个值消失,永远不会重新出现......”该帖子中建议的解决方法是添加一个空项目到列表中。就我而言,因为我使用的是字典,所以添加'':[]因为字典中的第一项解决了问题。这是唯一的解决方案吗?我讨厌将神器引入我的字典。这是代码:

import tkinter as tk
from tkinter import ttk
from tkinter import messagebox

class App:

    def __init__(self, master):

        master.title("Continental System")

        self.dict = {'':[], 'Asia': ['Japan', 'China', 'Malasia'],
                     'Europe': ['Germany', 'France', 'Switzerland'],
                     'Africa': ['Nigeria', 'Kenya', 'Ethiopia']}
        self.frame1 = ttk.Frame(master)
        self.frame1.pack()
        self.frame2 = ttk.Frame(master)
        self.frame2.pack()
        self.variable_a = tk.StringVar()
        self.variable_b = tk.StringVar()
        self.variable_a.trace('w', self.updateoptions)
        self.optionmenu_a = ttk.OptionMenu(self.frame1, self.variable_a, *self.dict.keys())
        self.variable_a.set("Asia")
        self.optionmenu_a.grid(row = 0, column = 0)
        self.optionmenu_b = ttk.OptionMenu(self.frame1, self.variable_b, '')
        self.optionmenu_b.grid(row = 0, column = 1)
        self.btn = ttk.Button(self.frame2 , text="Submit", width=8, command=self.submit)
        self.btn.grid(row=0, column=1, padx=20, pady=20)

    def updateoptions(self, *args):
        countries = self.dict[self.variable_a.get()]
        self.variable_b.set(countries[0])
        menu = self.optionmenu_b['menu']
        menu.delete(0, 'end')
        for country in countries:
            menu.add_command(label=country, command=lambda country=country: self.variable_b.set(country))

    def submit(self, *args):
        var1 = self.variable_a.get()
        var2 = self.variable_b.get()
        if messagebox.askokcancel("Confirm Selection", "Confirm your selection: " + var1 + ' ' + var2 + ". Do you wish to continue?"):
            print(var1, var2)

    def set_window(self, *args):
        w = 800 
        h = 500
        ws = root.winfo_screenwidth()
        hs = root.winfo_screenheight()
        x = (ws/2) - (w/2)
        y = (hs/2) - (h/2)
        root.geometry('%dx%d+%d+%d' % (w, h, x, y))


root = tk.Tk()
app = App(root)
app.set_window()
root.mainloop()

我还收到一些错误消息,包括AttributeError: 'App' object has no attribute 'optionmenu_b'这似乎已在我上面第一个问题的答案中得到解决。

Exception in Tkinter callback
Traceback (most recent call last):
  File "C:\Python34\lib\tkinter\__init__.py", line 1487, in __call__
    return self.func(*args)
  File "C:\Python34\tk1_version2.py", line 32, in updateoptions
    menu = self.optionmenu_b['menu']
AttributeError: 'App' object has no attribute 'optionmenu_b'

Python 版本 3.4.1


你引用的那个帖子是不正确的。您不需要将空格作为列表中的第一项。的签名ttk.OptionMenu命令需要默认值作为变量名称后的第一个参数。

您不需要向字典中添加空项目。你do创建选项菜单时需要添加默认值:

self.optionmenu_a = ttk.OptionMenu(self.frame1, self.variable_a, "Asia", *self.dict.keys())

一个稍微好一点的解决方案是获取键列表并将它们保存到列表中。对列表进行排序,然后使用列表的第一个元素作为默认值:

options = sorted(self.dict.keys())
self.optionmenu_a = ttk.OptionMenu(self.frame1, self.variable_a, options[0], *options)

收到错误的原因是因为您对调用引用函数的变量有跟踪self.optionmenu_b,但您最初设置该变量before你创造self.optionmenu_b。简单的解决方案是首先创建第二个菜单。

self.optionmenu_b = ttk.OptionMenu(...)
self.optionmenu_a = ttk.OptionMenu(...)
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

有关 tkinter optionmenu 第一个选项消失的更多信息 的相关文章

随机推荐