I have a custom Frame
with an update method that I want to call every time the user switches tab in a notebook using python2.7 ttk
.
My first thought was to intercept some "tab switch event", get the frame from the event and call the update method. However, googling this yields no good results. I can't seem to catch the event, nor get the frame from a "tab click event" in a good way. My current solution below works okay but I'm looking for a better alternative. (Also with my real update method I get some nasty alloc errors).
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()
As you can imagine this becomes very non-DRY as the amount of tabs increases...
You can bind to the <Visibility>
or <Map>
event of the frame. For example:
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()
Instead of
def tab_switch():
# see question...
nb.bind("<Button-1>", tab_switch)
you can do the following trick
b.bind("<<NotebookTabChanged>>",
lambda event: event.widget.winfo_children()[event.widget.index("current")].update())
This also removes the need to call
f1.update() # Initial update of first displayed tab
However, the solution proposed by @BryanOakley might work better when you have different types of frames where you cannot be sure if an .update()
method exists.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.