![](/img/trans.png)
[英]python-tkinter how to get one more argument in OptionMenu-command
[英]Tkinter Python: How to pass more than one argument through a lambda function in an OptionMenu
因此,在标题建议时,我无法在更改选项菜单时,我遇到了在我想调用的函数中的两个参数。
这是下面的代码:
OPTIONS = [
"Fire",
"Ice",
"Storm",
"Life",
"Myth",
"Death",
"Balance"
]
var = StringVar(frame)
var.set("Select School") # initial value
option = OptionMenu(frame, var,*OPTIONS,command= lambda frame,var : changeSchool(frame,var))
option.grid(row=0,column=0,sticky=(N,W))
我做了一些研究,我认为我已经正确地完成了所有事情,但是当我在选项菜单中选择一个选项时出现以下错误:
Exception in Tkinter callback
Traceback (most recent call last):
File "C:\Users\Gunner\AppData\Local\Programs\Python\Python35-32\lib\tkinter\__init__.py", line 1549, in __call__
return self.func(*args)
File "C:\Users\Gunner\AppData\Local\Programs\Python\Python35-32\lib\tkinter\__init__.py", line 3287, in __call__
self.__callback(self.__value, *args)
TypeError: <lambda>() missing 1 required positional argument: 'var'
我以为我已经将 var 传入 changeSchool 函数。
我感谢任何帮助!
编辑:这是我为那些希望看到它的人提供的 changeSchool 函数:
def changeSchool(frame,school):
print (school)
WizTool.schoolType = school
self.initBT(frame,WizTool.schoolType)
print (WizTool.schoolType)
编辑:这是整个程序(显示框架不在范围内)
from tkinter import *
from tkinter import ttk
from functools import partial
import webbrowser
import pprint
class WizTool:
schoolType = "Fire"
#initialize the GUI
def __init__(self, master):
content = ttk.Frame(master, padding=(3,3,12,12))
frame = ttk.LabelFrame(content, borderwidth=5, relief="sunken", width=400, height=400,padding=(3,3,12,12),text = "Blade Tracker")
content.grid(column=0,row=0,sticky=(N,S,E,W))
frame.grid(column=0, row=0, columnspan=4, sticky=(N, S, E, W))
self.master = master
self.initUI(content)
self.initBT(frame,WizTool.schoolType)
def initUI(self,frame):
self.master.title("Bootstrapper")
def changeSchool(frame,school):
print (school)
WizTool.schoolType = school
self.initBT(frame,WizTool.schoolType)
print (WizTool.schoolType)
def initBT(self,frame,mySchool):
#option menu for selecting school
OPTIONS = [
"Fire",
"Ice",
"Storm",
"Life",
"Myth",
"Death",
"Balance"
]
var = StringVar(frame)
var.set("Select School") # initial value
option = OptionMenu(frame, var,*OPTIONS,command= lambda frame,var : changeSchool(frame,var))
option.grid(row=0,column=0,sticky=(N,W))
def main():
root = Tk()
root.geometry("800x500+300+300")
app = WizTool(root)
root.mainloop()
main()
OptionMenu
小部件的command
函数只接受一个参数: selected item
。
command
函数吗? 回答:没有。command
函数? 答:蟒蛇。 Python 将您指定的函数存储在某处,然后在您在 OptionsMenu 中进行选择后的某个时间,python 调用command
函数。 因此,python 可以决定将多少个参数传递给command
函数,结果是 python 使用一个参数调用command
函数:
command(selection)
你怎么知道python用一个参数调用command
函数? 答:你检查文档。
如果您在文档中找不到任何描述您需要分配给command
的函数类型的内容,会发生什么? 答:你测试一下。
第一的:
...
...
def do_stuff(x):
print(x)
tk.OptionMenu(
root,
str_var,
*OPTIONS,
command=do_stuff).pack()
...
...
--output:--
Storm
下一个:
...
...
def do_stuff(x, y):
print(x, y)
tk.OptionMenu(
root,
str_var,
*OPTIONS,
command=do_stuff).pack()
...
...
--output:--
> TypeError: do_stuff() missing 1 required positional argument: 'y'
有多种方法可以解决这个问题......
使用 python 的范围规则:
import tkinter as tk
OPTIONS = [
"Fire",
"Ice",
"Storm",
"Life",
"Myth",
"Death",
"Balance"
]
root = tk.Tk()
root.title("Hello")
root.geometry("300x200+10+100")
frame = [1, 2, 3]
def do_stuff(selection):
print(selection, frame) #frame is visible inside the def.
str_var = tk.StringVar(root)
str_var.set(OPTIONS[0]) # default value
tk.OptionMenu(
root,
str_var,
*OPTIONS,
command=do_stuff
).pack()
root.mainloop()
但是让函数操作全局变量并不是一个好主意,所以你可以......
使用包装函数:
import tkinter as tk
OPTIONS = [
"Fire",
"Ice",
"Storm",
"Life",
"Myth",
"Death",
"Balance"
]
root = tk.Tk()
root.title("Hello")
root.geometry("300x200+10+100")
def wrapper(other):
def do_stuff(selection):
print(selection, other)
return do_stuff
str_var = tk.StringVar(root)
str_var.set(OPTIONS[0]) # default value
tk.OptionMenu(
root,
str_var,
*OPTIONS,
command=wrapper('xxxx') #This actually executes wrapper(), and a
#function call in your code is replaced
#by its return value--which happens to
#be the name of a function that takes one
#argument. The one arg function name is
#then assigned to command.
).pack()
root.mainloop()
为额外的参数变量使用默认值:
frame = [1, 2, 3]
def do_stuff(selection, other=frame): #<****HERE****
print(selection, other)
str_var = tk.StringVar(root)
str_var.set(OPTIONS[0]) # default value
tk.OptionMenu(
root,
str_var,
*OPTIONS,
command=do_stuff
).pack()
警告:参数变量的默认值有其自身的问题。 默认值在定义函数时分配一次。 随后,无论您执行该函数多少次,默认值都将使用相同的值。 这意味着如果默认值是一个列表,并且第一次调用该函数时更改了该列表,那么下次调用该函数时,默认值将是更改后的列表。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.