在 ttk.Notebook 中更新选项卡开关上的框架
Update frame on tab switch in ttk.Notebook
我有一个带有更新方法的自定义 Frame
,每次用户使用 python2.7 ttk
在笔记本中切换选项卡时我都想调用该方法。
我的第一个想法是拦截一些"tab switch event",从事件中获取帧并调用更新方法。但是,谷歌搜索不会产生好的结果。我似乎无法捕捉到事件,也无法很好地从 "tab click event" 获取帧。我下面的当前解决方案工作正常,但我正在寻找更好的选择。 (还有我真正的更新方法,我得到了一些讨厌的分配错误)。
import ttk
import Tkinter as tk
class MyFrame(ttk.Frame):
def __init__(self, master, name):
ttk.Frame.__init__(self, master)
self.name = name
self.pack()
def update(self):
# Update the contents of the frame...
print "Updating %s" % self.name
class App():
def __init__(self):
root = tk.Tk()
nb = ttk.Notebook(root)
f1_name = "Tab1"
f2_name = "Tab2"
f1 = MyFrame(nb, f1_name)
f2 = MyFrame(nb, f2_name)
nb.add(f1, text=f1_name)
nb.add(f2, text=f2_name)
def tab_switch(event):
if event.widget.identify(event.x, event.y) == "label":
index = event.widget.index("@%d,%d" % (event.x, event.y))
title = event.widget.tab(index, "text")
if title == f1_name:
f1.update()
elif title == f2_name:
f2.update()
# and so on...
nb.bind("<Button-1>", tab_switch)
nb.pack(fill="both", expand=True)
f1.update() # Initial update of first displayed tab
root.geometry("200x200")
root.mainloop()
App()
正如您可以想象的那样,随着选项卡数量的增加,这变得非常不干...
您可以绑定到框架的 <Visibility>
或 <Map>
事件。例如:
class MyFrame(ttk.Frame):
def __init__(self, master, name):
ttk.Frame.__init__(self, master)
self.name = name
self.pack()
self.bind("<Visibility>", self.on_visibility)
def on_visibility(self, event):
self.update()
而不是
def tab_switch():
# see question...
nb.bind("<Button-1>", tab_switch)
你可以做以下技巧
b.bind("<<NotebookTabChanged>>",
lambda event: event.widget.winfo_children()[event.widget.index("current")].update())
这也消除了调用
的需要
f1.update() # Initial update of first displayed tab
但是,@BryanOakley 提出的解决方案可能在您有不同类型的帧时效果更好,您无法确定是否存在 .update()
方法。
我有一个带有更新方法的自定义 Frame
,每次用户使用 python2.7 ttk
在笔记本中切换选项卡时我都想调用该方法。
我的第一个想法是拦截一些"tab switch event",从事件中获取帧并调用更新方法。但是,谷歌搜索不会产生好的结果。我似乎无法捕捉到事件,也无法很好地从 "tab click event" 获取帧。我下面的当前解决方案工作正常,但我正在寻找更好的选择。 (还有我真正的更新方法,我得到了一些讨厌的分配错误)。
import ttk
import Tkinter as tk
class MyFrame(ttk.Frame):
def __init__(self, master, name):
ttk.Frame.__init__(self, master)
self.name = name
self.pack()
def update(self):
# Update the contents of the frame...
print "Updating %s" % self.name
class App():
def __init__(self):
root = tk.Tk()
nb = ttk.Notebook(root)
f1_name = "Tab1"
f2_name = "Tab2"
f1 = MyFrame(nb, f1_name)
f2 = MyFrame(nb, f2_name)
nb.add(f1, text=f1_name)
nb.add(f2, text=f2_name)
def tab_switch(event):
if event.widget.identify(event.x, event.y) == "label":
index = event.widget.index("@%d,%d" % (event.x, event.y))
title = event.widget.tab(index, "text")
if title == f1_name:
f1.update()
elif title == f2_name:
f2.update()
# and so on...
nb.bind("<Button-1>", tab_switch)
nb.pack(fill="both", expand=True)
f1.update() # Initial update of first displayed tab
root.geometry("200x200")
root.mainloop()
App()
正如您可以想象的那样,随着选项卡数量的增加,这变得非常不干...
您可以绑定到框架的 <Visibility>
或 <Map>
事件。例如:
class MyFrame(ttk.Frame):
def __init__(self, master, name):
ttk.Frame.__init__(self, master)
self.name = name
self.pack()
self.bind("<Visibility>", self.on_visibility)
def on_visibility(self, event):
self.update()
而不是
def tab_switch():
# see question...
nb.bind("<Button-1>", tab_switch)
你可以做以下技巧
b.bind("<<NotebookTabChanged>>",
lambda event: event.widget.winfo_children()[event.widget.index("current")].update())
这也消除了调用
的需要f1.update() # Initial update of first displayed tab
但是,@BryanOakley 提出的解决方案可能在您有不同类型的帧时效果更好,您无法确定是否存在 .update()
方法。