我有Tkinter的应用程序,例如:
from Tkinter import *
from ttk import *
class MyMenu(Menu):
....
class MyNotebook(Notebook):
....
tk=Tk()
f1=Frame(master=tk)
f2=Frame(master=tk)
menu=MyMenu(master=f1)
notebook=MyNotebook(master=f2)
我想在command
中添加menu
,这会在notebook
中添加新标签。我怎么能这样做?
P.S。 f1 != f2
这很重要!
P.P.S。在commands
中用作menu
的函数可能位于另一个文件
答案 0 :(得分:1)
菜单中不需要其中一个框架,因为它应该配置窗口而不是与几何管理器一起放置。类似的东西可以完成这项工作:
# ...
def add_tab():
text = "Tab {}".format(len(notebook.tabs()))
frame = Frame(notebook, width=100, height=100)
notebook.add(frame, text=text)
menu=MyMenu()
menu.add_command(label="Add tab", command=add_tab)
tk.config(menu=menu)
但是,我建议您:a)定义一个类而不是使用全局变量;和b)不要使用import *
,因为Tkinter ttk对不同的类使用相同的名称。它不仅更有条理,而且更容易阅读:
import Tkinter as tk
import ttk
class MyMenu(tk.Menu):
pass
class MyNotebook(ttk.Notebook):
pass
class App(tk.Tk):
def __init__(self):
tk.Tk.__init__(self)
self.frame = ttk.Frame(self)
self.notebook = MyNotebook(self.frame)
self.frame.pack()
self.notebook.pack()
self.add_tab()
menu = MyMenu()
menu.add_command(label="Add tab", command=self.add_tab)
self.config(menu=menu)
def add_tab(self):
text = "Tab {}".format(len(self.notebook.tabs()))
frame = ttk.Frame(self.notebook, width=100, height=100)
self.notebook.add(frame, text=text)
app = App()
app.mainloop()
答案 1 :(得分:1)
解决方案很简单:对于类A的实例与类B的实例进行交互,类A需要对类B的实例的引用。这意味着您需要将其传递给构造函数,或者设置如果在创作之后。例如:
class MyMenu(Menu):
def __init__(self, notebook):
...
self.add_command("New page", command=notebook.add(...))
...
notebook = Notebook(...)
menu = MyMenu(notebook)
另一种方式 - 我认为更好 - 是传递有时称为控制器的东西 - 一个知道所有小部件的类,或者提供小部件的接口。例如,您可以将您的应用程序实现为类,并使用该实例作为您的控制器:
class MyMenu(Menu)
def __init__(self, app=None):
...
self.add_command(..., command=app.add_tab)
class App(Tk):
def __init__(self):
...
self.menu = MyMenu(self, controller=self)
self.notebook = Notebook(...)
...
def add_tab(self, label):
frame = Frame(self)
self.notebook.add(frame, text=label)
app = App()
app.mainloop()