关于如何为事件处理程序声明额外参数的New Mexico Tech website,提供了以下示例。
def __createWidgets(self):
…
self.cbList = [] # Create the checkbutton list
for i in range(10):
cb = tk.Checkbutton(self, …)
self.cbList.append(cb)
cb.grid( row=1, column=i)
def handler(event, self=self, i=i): ## 1
return self.__cbHandler(event, i)
cb.bind('<Button-1>', handler)
…
def __cbHandler(self, event, cbNumber):
…
备注## 1:这些行定义了一个期望的新函数处理程序 三个论点。第一个参数是传递给all的Event对象 事件处理程序,第二个和第三个参数将设置为 它们的默认值 - 我们需要传递它的额外参数。
问题:
self=self
中的def handler(...)
争论是否需要通过
“自我”进入事件处理程序de __cbHandler(...)
?默认情况下,“self”本身并不存在于事件处理程序中吗?self=self
,则测试代码的工作方式相同。是否存在事件处理方案,其中声明self=self
参数是强制/必要的?测试代码:
#!/usr/bin/python3
# -*- coding: utf-8 -*-
try:
import tkinter as tk # Python 3 tkinter modules
except ImportError:
import Tkinter as tk # Python 2 tkinter modules
class NewListbox(tk.Frame):
def __init__(self, parent, lb_values1, lb_values2):
tk.Frame.__init__(self, parent)
self.lb_values = tk.StringVar()
self.lb_values.set(lb_values1)
self.listbox = tk.Listbox(self, listvariable=self.lb_values)
self.listbox.grid(row=2, column=0, sticky='nsew')
# Having self=self and removing seems to make no difference.
# self, appears to be pass on to the method def _update().
def handler(event, self=self, values2=lb_values2):
return self._update(event, lb_values2)
self.listbox.bind("<Button-1>", handler)
def _update(self, event, newvalues):
self.lb_values.set(newvalues)
class App(tk.Frame):
def __init__(self, parent):
tk.Frame.__init__(self, parent)
self.grid(row=0, column=0, sticky='nsew')
nlist1 = ['Peter', 'Scotty', 'Walter', 'Scott', 'Mary']
nlist2 = ['Sarah', 'Jane', 'Oscar', 'Walley', 'Faith']
self.lb = NewListbox(self, nlist1, nlist2)
self.lb.grid(row=0, column=0, sticky='nsew')
if __name__ == '__main__':
root = tk.Tk()
app = App(root)
app.mainloop()
原创方法(见下文):
优点:易于实施。
实施成本:增加小部件的属性数量。
#!/usr/bin/python3
# -*- coding: utf-8 -*-
try:
import tkinter as tk # Python 3 tkinter modules
except ImportError:
import Tkinter as tk # Python 2 tkinter modules
class NewListbox(tk.Frame):
def __init__(self, parent, lb_values1, lb_values2):
tk.Frame.__init__(self, parent)
self.lb_values = tk.StringVar()
self.lb_values.set(lb_values1)
self.lb_values2 = lb_values2 # create new attribute to store lb_values2
self.listbox = tk.Listbox(self, listvariable=self.lb_values)
self.listbox.grid(row=2, column=0, sticky='nsew')
self.listbox.bind("<Button-1>", self._update)
def _update(self, event):
self.lb_values.set(self.lb_values2) #load new attribute.
class App(tk.Frame):
def __init__(self, parent):
tk.Frame.__init__(self, parent)
self.grid(row=0, column=0, sticky='nsew')
nlist1 = ['Peter', 'Scotty', 'Walter', 'Scott', 'Mary']
nlist2 = ['Sarah', 'Jane', 'Oscar', 'Walley', 'Faith']
self.lb = NewListbox(self, nlist1, nlist2)
self.lb.grid(row=0, column=0, sticky='nsew')
if __name__ == '__main__':
root = tk.Tk()
app = App(root)
app.mainloop()