在 Tkinter 中,我想创建一个动态按钮,当用户在 OptionMenu 窗口小部件中选择一个函数时,该按钮就会调用该函数。
以下是我当前的代码:
from Tkinter import *
import Tkinter
import tkMessageBox
master = Tk()
myvar_1 = IntVar()
myvar_2 = IntVar()
myvar_3 = StringVar()
myvar_4 = IntVar()
myvar_5 = IntVar()
myvar_6 = IntVar()
myvar_7 = IntVar()
#
def daily_return(*args):
print "The start date is ", var.get(), "+", myvar_1.get(),"-", myvar_4.get(), "-", myvar_6.get(), "and the end date is", myvar_2.get(),"-", myvar_5.get(), "-", myvar_7.get(), " for the stock ticker:", myvar_3.get(), "."
def cumulative_return(*args):
print "The start date is ", myvar_1.get(), "the cumulative return."
def value_at_risk(*args):
print "The start date is ", myvar_1.get(), "the value at risk."
Label(master, text="Start Date (DD-MM-YYYY)").grid(row=0)
Label(master, text="End Date (DD-MM-YYYY)").grid(row=1)
Label(master, text="Stock Ticker").grid(row=2)
##
text_entry_1 = Entry(master, textvariable=myvar_1)
text_entry_1.pack()
text_entry_2 = Entry(master, textvariable=myvar_2)
text_entry_2.pack()
text_entry_3 = Entry(master, textvariable=myvar_3)
text_entry_3.pack()
text_entry_4 = Entry(master, textvariable=myvar_4)
text_entry_4.pack()
text_entry_5 = Entry(master, textvariable=myvar_5)
text_entry_5.pack()
text_entry_6 = Entry(master, textvariable=myvar_6)
text_entry_6.pack()
text_entry_7 = Entry(master, textvariable=myvar_7)
text_entry_7.pack()
#
var = StringVar()
var.set('Choose function')
choices = ['cumulative_return', 'daily_return', 'value_at_risk']
option = OptionMenu(master, var, *choices)
option.pack()
##
text_entry_1.grid(row=0, column=1)
text_entry_2.grid(row=1, column=1)
text_entry_3.grid(row=2, column=1)
text_entry_4.grid(row=0, column=2)
text_entry_5.grid(row=1, column=2)
text_entry_6.grid(row=0, column=3)
text_entry_7.grid(row=1, column=3)
option.grid(row=4, column=0)
sf = "Quant Program"
#
def quit():
global root
master.destroy()
#
master.title("Quant Program")
Button(master, text='Quit', command=quit).grid(row=4, column=4, sticky=W, pady=4)
Button(master, text='Show', command=daily_return).grid(row=4, column=1, sticky=W, pady=4)
mainloop( )
在上面的代码中,我尝试通过将 "command=daily_return" 替换为 "command=var" 来创建动态按钮,但它不起作用。
2、解决方案
为了解决这个问题,我们可以使用一个映射来将 OptionMenu 窗口小部件中选择的函数名称映射到实际的函数。然后,我们可以使用这个映射来动态地调用所选函数。
以下是我修改后的代码:
from Tkinter import *
import Tkinter
import tkMessageBox
master = Tk()
myvar_1 = IntVar()
myvar_2 = IntVar()
myvar_3 = StringVar()
myvar_4 = IntVar()
myvar_5 = IntVar()
myvar_6 = IntVar()
myvar_7 = IntVar()
#
def daily_return(*args):
print "The start date is ", var.get(), "+", myvar_1.get(),"-", myvar_4.get(), "-", myvar_6.get(), "and the end date is", myvar_2.get(),"-", myvar_5.get(), "-", myvar_7.get(), " for the stock ticker:", myvar_3.get(), "."
def cumulative_return(*args):
print "The start date is ", myvar_1.get(), "the cumulative return."
def value_at_risk(*args):
print "The start date is ", myvar_1.get(), "the value at risk."
# 定义函数映射
func_map = {
"daily_choices": daily_choices,
"value_at_risk": value_at_risk,
"cumulative_return": cumulative_return,
}
Label(master, text="Start Date (DD-MM-YYYY)").grid(row=0)
Label(master, text="End Date (DD-MM-YYYY)").grid(row=1)
Label(master, text="Stock Ticker").grid(row=2)
##
text_entry_1 = Entry(master, textvariable=myvar_1)
text_entry_1.pack()
text_entry_2 = Entry(master, textvariable=myvar_2)
text_entry_2.pack()
text_entry_3 = Entry(master, textvariable=myvar_3)
text_entry_3.pack()
text_entry_4 = Entry(master, textvariable=myvar_4)
text_entry_4.pack()
text_entry_5 = Entry(master, textvariable=myvar_5)
text_entry_5.pack()
text_entry_6 = Entry(master, textvariable=myvar_6)
text_entry_6.pack()
text_entry_7 = Entry(master, textvariable=myvar_7)
text_entry_7.pack()
#
var = StringVar()
var.set('Choose function')
choices = ['cumulative_return', 'daily_return', 'value_at_risk']
option = OptionMenu(master, var, *choices)
option.pack()
##
text_entry_1.grid(row=0, column=1)
text_entry_2.grid(row=1, column=1)
text_entry_3.grid(row=2, column=1)
text_entry_4.grid(row=0, column=2)
text_entry_5.grid(row=1, column=2)
text_entry_6.grid(row=0, column=3)
text_entry_7.grid(row=1, column=3)
option.grid(row=4, column=0)
sf = "Quant Program"
#
def quit():
global root
master.destroy()
#
master.title("Quant Program")
# 创建动态按钮
button = Button(master, text='Show', command=lambda: func_map[var.get()]())
button.grid(row=4, column=1, sticky=W, pady=4)
Button(master, text='Quit', command=quit).grid(row=4, column=4, sticky=W, pady=4)
mainloop( )
在修改后的代码中,我们使用 lambda 函数来动态地调用所选函数。lambda 函数接受一个参数 var.get(),该参数返回 OptionMenu 窗口小部件中选择的函数名称。然后,lambda 函数使用 func_map 映射来获取实际的函数,并调用该函数。
现在,当用户在 OptionMenu 窗口小部件中选择一个函数时,动态按钮将调用该函数。