Tkinter中窗口的不同元素的交互

时间:2013-05-27 20:28:36

标签: python tkinter

我有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的函数可能位于另一个文件

2 个答案:

答案 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()