Tkinter optionmenu 不允许我根据所做的选择传递要更新的对象的框架
Tkinter optionmenu won't allow me to pass the frame of the object I want to update depending on the choice made
我有一个框架列表,每个框架都有一个带有相同选项列表的选项菜单。当在该特定选项菜单中做出选择时,我只能更改最后一个条目小部件,而不是相应的小部件。在其他小部件中,我已经能够使用类似 "lambda F=F:function(args)" 的东西,但它在这里不起作用。
我试过跟踪选项菜单中的变量,我试过包装函数,我试过选项菜单小部件命令部分中 lambda 的所有组合。大多数方法都会产生错误,有些方法(如所附的方法)会修改底部 frame/entry 而不是正确的对应方法。
这似乎不应该太难。如果选择的顶部框架的选项是 "Continuous" 或 "Discrete",它旁边的条目应该是 'normal' 状态,带有“?..?”在框中,如果它是分类的,它应该更改为 'disabled' 没有内容。如果我能以某种方式将 Frame 字典键传递给 "updateOnChange" 函数,我可以很容易地做到这一点,但我不能,它只允许传递一个参数,那就是 mType[F] 的字符串值。
from tkinter import *
def updateOnChange(type):
print(type)
if type.upper()=='CATEGORICAL':
rangeEntry[F].delete(0,END)
rangeEntry[F].config(state='disabled')
print("runCat")
else:
rangeEntry[F].config(state='normal')
rangeEntry[F].delete(0,END)
rangeEntry[F].insert(0,'?..?')
print("runCont")
mType={}
frame={}
om={}
rangeEntry={}
root=Tk()
Frames=['FrameOne','FrameTwo']
miningTypes=['Continuous','Categorical','Discrete']
for F in Frames:
mType[F]=StringVar(root)
if F=='FrameOne':
mType[F].set("Continuous")
else:
mType[F].set("Categorical")
frame[F]=Frame(root,borderwidth=3,relief=SUNKEN)
frame[F].pack(side=TOP,fill=X)
rangeEntry[F]=Entry(frame[F],width=20,font=("Arial",12))
om[F]=OptionMenu(frame[F],mType[F],*miningTypes,command=updateOnChange)
om[F].pack(side=LEFT)
rangeEntry[F].pack(side=LEFT)
mainloop()
``
您的 updateOnChange
函数将要更改的条目硬编码为 rangeEntry[F]
,它指向在您的 for
循环中创建的最后一个 Entry
小部件。要正确关联每个条目,您应该将小部件作为参数传递:
def updateOnChange(type, entry):
if type.upper()=='CATEGORICAL':
entry.delete(0,END)
entry.config(state='disabled')
print("runCat")
else:
entry.config(state='normal')
entry.delete(0,END)
entry.insert(0,'?..?')
print("runCont")
然后在你的command
中传递参数:
om[F]= OptionMenu(frame[F],mType[F],*miningTypes,command=lambda e, i=rangeEntry[F]: updateOnChange(e, i))
我有一个框架列表,每个框架都有一个带有相同选项列表的选项菜单。当在该特定选项菜单中做出选择时,我只能更改最后一个条目小部件,而不是相应的小部件。在其他小部件中,我已经能够使用类似 "lambda F=F:function(args)" 的东西,但它在这里不起作用。
我试过跟踪选项菜单中的变量,我试过包装函数,我试过选项菜单小部件命令部分中 lambda 的所有组合。大多数方法都会产生错误,有些方法(如所附的方法)会修改底部 frame/entry 而不是正确的对应方法。
这似乎不应该太难。如果选择的顶部框架的选项是 "Continuous" 或 "Discrete",它旁边的条目应该是 'normal' 状态,带有“?..?”在框中,如果它是分类的,它应该更改为 'disabled' 没有内容。如果我能以某种方式将 Frame 字典键传递给 "updateOnChange" 函数,我可以很容易地做到这一点,但我不能,它只允许传递一个参数,那就是 mType[F] 的字符串值。
from tkinter import *
def updateOnChange(type):
print(type)
if type.upper()=='CATEGORICAL':
rangeEntry[F].delete(0,END)
rangeEntry[F].config(state='disabled')
print("runCat")
else:
rangeEntry[F].config(state='normal')
rangeEntry[F].delete(0,END)
rangeEntry[F].insert(0,'?..?')
print("runCont")
mType={}
frame={}
om={}
rangeEntry={}
root=Tk()
Frames=['FrameOne','FrameTwo']
miningTypes=['Continuous','Categorical','Discrete']
for F in Frames:
mType[F]=StringVar(root)
if F=='FrameOne':
mType[F].set("Continuous")
else:
mType[F].set("Categorical")
frame[F]=Frame(root,borderwidth=3,relief=SUNKEN)
frame[F].pack(side=TOP,fill=X)
rangeEntry[F]=Entry(frame[F],width=20,font=("Arial",12))
om[F]=OptionMenu(frame[F],mType[F],*miningTypes,command=updateOnChange)
om[F].pack(side=LEFT)
rangeEntry[F].pack(side=LEFT)
mainloop()
``
您的 updateOnChange
函数将要更改的条目硬编码为 rangeEntry[F]
,它指向在您的 for
循环中创建的最后一个 Entry
小部件。要正确关联每个条目,您应该将小部件作为参数传递:
def updateOnChange(type, entry):
if type.upper()=='CATEGORICAL':
entry.delete(0,END)
entry.config(state='disabled')
print("runCat")
else:
entry.config(state='normal')
entry.delete(0,END)
entry.insert(0,'?..?')
print("runCont")
然后在你的command
中传递参数:
om[F]= OptionMenu(frame[F],mType[F],*miningTypes,command=lambda e, i=rangeEntry[F]: updateOnChange(e, i))