单击重置按钮(重置在 OptionMenus 上所做的选择)后,OptionMenu 对其他 OptionMenus 的依赖性不起作用
OptionMenu's dependency on other OptionMenus is not working after the Reset Button (which resets the selections made on the OptionMenus) is clicked
我正在尝试使用 Tkinter 在 Python 中创建一个 GUI 应用程序 UNIT CONVERTER。我创建了一个主要的 OptionMenu 和两个其他的 OptionMenus。这另外两个 OptionMenus 依赖于主 OptionMenu i.e.upon select 从主 OptionMenu 中获取值,其他两个 OptionMenus 中的值列表发生变化。我创建了两个按钮“转换”和“重置”。在重置按钮中,我试图重置所有三个 OptionMenus 上的 selections。
源代码
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()
问题陈述:
单击重置时,逻辑成功运行,但当我再次 select 主 OptionMenu 中的新值时,相应的值列表未反映在其他两个 OptionMenus 中。我无法理解“在我单击重置按钮后,为什么当我更改主 OptionMenu 的值时我的其他两个下拉菜单没有反映相应的值”。
您忘记将 updateSubLists
作为 tk._setit(...)
的第三个参数传递给 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))
...
我正在尝试使用 Tkinter 在 Python 中创建一个 GUI 应用程序 UNIT CONVERTER。我创建了一个主要的 OptionMenu 和两个其他的 OptionMenus。这另外两个 OptionMenus 依赖于主 OptionMenu i.e.upon select 从主 OptionMenu 中获取值,其他两个 OptionMenus 中的值列表发生变化。我创建了两个按钮“转换”和“重置”。在重置按钮中,我试图重置所有三个 OptionMenus 上的 selections。
源代码
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()
问题陈述: 单击重置时,逻辑成功运行,但当我再次 select 主 OptionMenu 中的新值时,相应的值列表未反映在其他两个 OptionMenus 中。我无法理解“在我单击重置按钮后,为什么当我更改主 OptionMenu 的值时我的其他两个下拉菜单没有反映相应的值”。
您忘记将 updateSubLists
作为 tk._setit(...)
的第三个参数传递给 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))
...