首页 > 解决方案 > 单击重置按钮(重置在 OptionMenus 上所做的选择)后,OptionMenu 对其他 OptionMenus 的依赖不起作用

问题描述

我正在尝试使用 Tkinter 创建一个 UNIT CONVERTER,它是 Python 中的 GUI 应用程序。我创建了一个主 OptionMenu 和两个其他 OptionMenus。这另外两个 OptionMenus 依赖于主 OptionMenu,即当从主 OptionMenu 中选择一个值时,其他两个 OptionMenus 中的值列表会发生变化。我创建了两个按钮“转换”和“重置”。在重置按钮中,我试图重置所有三个选项菜单上的选择。

源代码

import tkinter as tk
from tkinter import messagebox
from math import * 


root = tk.Tk()
root.title("Unit Converter")
root.geometry("600x400")

# A function for updating the dropdown lists upon selecting the operation.
def updateSubLists(self):
    y.set('')
    z.set('')
    subUnitListFrom['menu'].delete(0,'end')
    subUnitListTo['menu'].delete(0,'end')
     
    for item in list(listOfUnits.get(x.get())):
        subUnitListFrom['menu'].add_command(label=item,command=tk._setit(y,item))
        subUnitListTo['menu'].add_command(label=item,command=tk._setit(z,item))
    
    y.set(list(listOfUnits.get(x.get()))[0])
    z.set(list(listOfUnits.get(x.get()))[0])

# A callback function to validate if the data entered is only digit or not.
def validateUserInput(input):
    """This method validates the data entered by the User to check if the entered data is a number or not."""
    if input.isdigit() == True:
        return True
    elif input == "":
        return True
    else:
        messagebox.showinfo("Information","Only number is allowed")
        return False
  

# A function for resetting the entries selected.
def resetEntries():
    """ This method helps in resetting the entries given as a input or selected by the User"""
    x.set("")
    unitList["menu"].delete(0,'end')
    for item in list(listOfUnits.keys()):
        unitList['menu'].add_command(label=item,command=tk._setit(x,item))
    x.set(list(listOfUnits.keys())[0])
    
    #updateSubLists('')
    y.set('')
    z.set('')
    subUnitListFrom['menu'].delete(0,'end')
    subUnitListTo['menu'].delete(0,'end')
     
    for item in list(listOfUnits.get(x.get())):
        subUnitListFrom['menu'].add_command(label=item,command=tk._setit(y,item))
        subUnitListTo['menu'].add_command(label=item,command=tk._setit(z,item))
    
    y.set(list(listOfUnits.get(x.get()))[0])
    z.set(list(listOfUnits.get(x.get()))[0])


# Lists and Sub-lists creation 
#listOfUnits = ['Area','Energy','Frequency','Length','Mass','Pressure','Speed','Temperature',
               #'Time','Volume']

listOfUnits = {"Area":['Square Kilometer','Squatre Meter','Square Mile','Square Yard','Square Foot','Square Inch','Hectare','Acre'],
            "Energy":['Joule','Kilo Joule','Gram Calorie','Kilo Calorie'],
            "Frequency":['Hertz','Kilohertz','Megahertz','Kilohertz'],
            "Length":['Kilometer','Meter','Centimeter','Millimeter','Micrometer','Nanometer','Mile','Yard','Foot','Inch'],
            "Mass":['Tonne','Kilogram','Microgram','Milligram','Gram','Pound','Ounce'],
            "Pressure":['Bar','Pascal','Pound per square inch','Standard atmosphere','Torr'],
            "Speed":['Miles per hour','Meter per second','Foot per second','Kilometer per hour','Knot'],
            "Temperature":['Celcius','Farhenheit','Kelvin'],
            "Time":['Nanosecond','Microsecond','Millisecond','Second','Minute','Hour','Day','Week','Month','Calender Year','Decade','Century'],
            "Volume":['Litre','Millilitre','Imperial Gallon','Imperial Pint']
           }

# label text for header title
headerLbl = tk.Label(root,text="UNIT CONVERTER",fg="black",bg="light grey",font = ("Times New Roman", 30,"bold","italic","underline"))
headerLbl.grid(row = 0,column = 1,columnspan = 3)

# Label text for conversion tye selection 
lbl1 = tk.Label(root,text="Type of Conversion:")
lbl1.grid(row = 1,column = 0,padx=20,pady=20)


# OptionMenu creation for the list of Units to select
global x 
x = tk.StringVar()
x.set(list(listOfUnits.keys())[0])
unitList = tk.OptionMenu(root,x,*listOfUnits.keys(),command=updateSubLists)
unitList.grid(row = 1,column = 1,padx=20,pady=40)

# Label text for conversion type selection 
lbl2 = tk.Label(root,text="From")
lbl2.grid(row = 2,column = 0)


# OptionMenu creation for the list of Sub Units to select.
global y 
y = tk.StringVar()
y.set(list(listOfUnits.get(x.get()))[0])
subUnitListFrom = tk.OptionMenu(root,y,*listOfUnits.get(x.get()))
subUnitListFrom.grid(row=2,column=1,padx=20,pady=40)


# Entry widget for From label
fromEntry = tk.Entry(root,width=20)
valid_info = root.register(validateUserInput)   # register the function for the validation
fromEntry.config(validate="key",validatecommand=(valid_info,'%P'))  # Adding the properties for validation elements
fromEntry.grid(row=2,column=2)

# Label text for conversion type selection 
lbl3 = tk.Label(root,text="To")
lbl3.grid(row = 3,column = 0)

# OptionMenu creation for the list of Sub Units to select.
global z 
z = tk.StringVar()
z.set(list(listOfUnits.get(x.get()))[0])
subUnitListTo = tk.OptionMenu(root,z,*listOfUnits.get(x.get()))
subUnitListTo.grid(row=3,column=1)

# Entry widget for From label
ToEntry = tk.Entry(root,width=20,state="readonly")
ToEntry.grid(row=3,column=2)

# Logic for the convert button
convert_button = tk.Button(root,text="CONVERT",fg="black",bg ="yellow",font=("Times New Roman",12,"bold"))
convert_button.grid(row=4,column=1,padx=20,pady=40)

# Logic for the reset button
reset_button = tk.Button(root,text="RESET",fg="black",bg="yellow",font=("Times New Roman",12,"bold"),command=resetEntries)
reset_button.grid(row=4,column=2,padx=20,pady=40)

root.mainloop()

问题陈述: 当点击重置时,逻辑工作成功,但是当我再次在主选项菜单中选择一个新值时,相应的值列表没有反映在其他两个选项菜单中。我无法理解“单击 Reset Button 后,为什么当我更改主 OptionMenu 的值时我的其他两个下拉菜单没有反映相应的值”。

标签: pythontkinterdependenciesdropdownoptionmenu

解决方案


updateSubLists您忘记作为tk._setit(...)inside的第三个参数传递resetEntries()

def resetEntries():
    """ This method helps in resetting the entries given as a input or selected by the User"""
    x.set("")
    unitList["menu"].delete(0,'end')
    for item in list(listOfUnits.keys()):
        unitList['menu'].add_command(label=item,command=tk._setit(x,item,updateSubLists))

    ...

推荐阅读