【发布时间】:2017-02-08 18:30:20
【问题描述】:
在一个 lambda 中执行多个语句是否可行?我的控制器中的app_data 字典有一个属性“listbox”,用于存储选定的列表框值。 SelectPage 上的按钮有一个 lambda 命令,可将帧更改为 NextPage。
frame switch 和 app_data set 语句都可以出现在双 lambda 中吗?如果是这样,这会是什么样子?还是这些操作必须单独发生(即在按钮单击事件中)?
更新 #1:
问题与 lambda 表达式无关,因为仅在 .set(1) 中添加一个常量(即 1)也不会保存。
更新 #2:
使用带有 doStuff(controller) 的 lambda 可以在一定程度上解决问题,但列表框引用会引发错误:
值 = self.listbox.get(self.listbox.curselection()) AttributeError: 'SelectPage' 对象没有属性 'listbox'
按钮:
button1 = ttk.Button(self, text='Next Page',
command=lambda:self.doStuff(controller))
doStuff():
def doStuff(self,controller):
controller.show_frame(NextPage)
controller.app_data["listbox"].set(1)
value = self.listbox.get(self.listbox.curselection())
print(value)
print("do Stuff successful")
完整代码:
from tkinter import *
from tkinter import ttk
class MyApp(Tk):
# Controller class
def __init__(self):
Tk.__init__(self)
# App data in controller
self.app_data = {"listbox": StringVar(),
"entry": StringVar(),
}
container = ttk.Frame(self)
container.pack(side="top", fill="both", expand = True)
self.frames = {}
for F in (SelectPage, NextPage):
frame = F(container, self)
self.frames[F] = frame
frame.grid(row=0, column=0, sticky = NSEW)
self.show_frame(SelectPage)
def show_frame(self, cont):
frame = self.frames[cont]
frame.tkraise()
def get_page(self,classname):
for page in self.frames.values():
if str(page.__class__.__name__) == classname:
return page
return None
class SelectPage(ttk.Frame):
def __init__(self, parent, controller):
self.controller = controller
ttk.Frame.__init__(self, parent)
ttk.Label(self, text='Select Page').grid(padx=(20,20), pady=(20,20))
listbox = Listbox(self,exportselection=0)
listbox.grid()
for item in [0,1,2,3,4,5]:
listbox.insert(END, item)
print (item)
entry1 = ttk.Entry(self, textvariable=self.controller.app_data["entry"], width=8)
entry1.grid()
button1 = ttk.Button(self, text='Next Page',
command=lambda:self.doStuff(controller)) # something like this lambda concept
button1.grid()
def doStuff(self,controller):
controller.show_frame(NextPage)
controller.app_data["listbox"].set(1)
value = self.listbox.get(self.listbox.curselection())
print(value)
print("do Stuff successful")
class NextPage(ttk.Frame):
def __init__(self, parent, controller):
self.controller = controller
ttk.Frame.__init__(self, parent)
ttk.Label(self, text='Next Page').grid(padx=(20,20), pady=(20,20))
button1 = ttk.Button(self, text='Select Page',
command=lambda: controller.show_frame(SelectPage))
button1.grid()
button2 = ttk.Button(self, text='press to print', command=self.print_it)
button2.grid()
def print_it(self):
value = self.controller.app_data["listbox"].get()
print ('The value stored in StartPage some_entry = ' + str(value))
value = self.controller.app_data["entry"].get()
print ('The value stored in StartPage some_entry = ' + str(value))
app = MyApp()
app.title('Multi-Page Test App')
app.mainloop()
【问题讨论】:
-
不要使用 lambda,使用
def的适当函数。注意:您可以在函数中定义函数,并在必要时使用它们的本地命名空间。 -
你尝试的时候发生了什么?您的代码是否按预期工作?
-
@Goyo 代码运行,但列表框项目未保存
-
更简单:
def doStuff()里面有语句,然后是command=doStuff。注意:doStuff,而不是doStuff()。