我试图推广在tkinter.ttk.Notebook
中添加按钮和选项卡。到目前为止,我拥有的是:
from tkinter.ttk import Notebook, Frame
from tkinter import Button, Tk
f1 = lambda: print("f1")
f2 = lambda: print("f2")
f3 = lambda: print("f3")
f4 = lambda: print("f4")
f5 = lambda: print("f5")
f6 = lambda: print("f6")
f7 = lambda: print("f7")
frames = ["F1", "F2", "F3"]
labels = [('f1', 'f2', 'f3'), ('f4', 'f5'), ('f6', 'f7')]
commands = [(f1, f2, f3), (f4, f5), (f6, f7)]
tk = Tk()
notebook = Notebook(tk)
for i, f in enumerate(frames):
frame = Frame(notebook)
notebook.add(frame, text=f)
for j, label in enumerate(labels[i]):
button = Button(frame, text=label, command=commands[i][j])
button.pack()
notebook.pack()
tk.mainloop()
现在,假设我希望函数f7
不打印字符串'f7'
,而是执行frame.quit
,这样我就可以退出笔记本了。
如何调用frame.quit
并保持上面代码的泛型?在for
循环之前,我不知道该怎么做。
我想到了两种方法。第一种是在lambdas之前创建一个空对象(使用此处描述的方法(,然后在调用frame
时正确定义该函数。
frame = type('', (), {})()
f1 = lambda: print("f1")
f2 = lambda: print("f2")
f3 = lambda: print("f3")
f4 = lambda: print("f4")
f5 = lambda: print("f5")
f6 = lambda: print("f6")
f7 = lambda: print(frame.quit)
如果你的几个函数要引用这个框架,你可以把一个引用传递给它,但每个lambda都需要把它作为一个参数。
from tkinter.ttk import Notebook, Frame
from tkinter import Button, Tk
f1 = lambda f: print("f1")
f2 = lambda f: print("f2")
f3 = lambda f: print("f3")
f4 = lambda f: print("f4")
f5 = lambda f: print("f5")
f6 = lambda f: print("f6")
f7 = lambda f: f.quit()
frames = ["F1", "F2", "F3"]
labels = [('f1', 'f2', 'f3'), ('f4', 'f5'), ('f6', 'f7')]
commands = [(f1, f2, f3), (f4, f5), (f6, f7)]
tk = Tk()
notebook = Notebook(tk)
for i, f in enumerate(frames):
frame = Frame(notebook)
notebook.add(frame, text=f)
for j, label in enumerate(labels[i]):
button = Button(frame, text=label, command= lambda: commands[i][j](frame))
button.pack()
notebook.pack()
tk.mainloop()
您需要进行一些更改来支持您想要的内容。
- 为定义的七个默认
F*
函数中的每一个添加一个通用*args
参数,这样,如果有任何参数传递给它们(如frame
(,它们就会工作 - 将
commands
变量从元组列表更改为列表列表,以使其子序列可变 - 使
Button
的command=
关键字参数值为lambda
,并包含多个参数,其中一些参数具有默认值。这使它能够在运行时查找值
from tkinter.ttk import Notebook, Frame
from tkinter import Button, Tk
f1 = lambda *args: print("f1")
f2 = lambda *args: print("f2")
f3 = lambda *args: print("f3")
f4 = lambda *args: print("f4")
f5 = lambda *args: print("f5")
f6 = lambda *args: print("f6")
f7 = lambda *args: print("f7")
frames = ["F1", "F2", "F3"]
labels = [('f1', 'f2', 'f3'), ('f4', 'f5'), ('f6', 'f7')]
commands = [[f1, f2, f3], [f4, f5], [f6, f7]] # CHANGED TO LIST OF SUBLISTS
tk = Tk()
notebook = Notebook(tk)
for i, f in enumerate(frames):
frame = Frame(notebook)
notebook.add(frame, text=f)
for j, label in enumerate(labels[i]):
button = Button(frame, text=label, command=lambda i=i, j=j: commands[i][j](frame))
button.pack()
notebook.pack()
commands[2][1] = lambda frame: frame.quit() # Change the F7 slot.
tk.mainloop()
我做了一些稍微不同的事情,它起了作用:
from tkinter.ttk import Notebook, Frame
from tkinter import Button, Tk
tk = Tk()
notebook = Notebook(tk)
f1 = lambda: print("f1")
f2 = lambda: print("f2")
f3 = lambda: print("f3")
f4 = lambda: print("f4")
f5 = lambda: print("f5")
f6 = lambda: print("f6")
f7 = lambda: notebook.quit()
frames = ["F1", "F2", "F3"]
labels = [('f1', 'f2', 'f3'), ('f4', 'f5'), ('f6', 'f7')]
commands = [(f1, f2, f3), (f4, f5), (f6, f7)]
for i, f in enumerate(frames):
frame = Frame(notebook)
notebook.add(frame, text=f)
for j, label in enumerate(labels[i]):
button = Button(frame, text=label, command=commands[i][j])
button.pack()
notebook.pack()
tk.mainloop()