Summary
In a Python Tkinter application ttk.Notebook, when I use it , how do I bind a keypress event so that it fires only when the tab containing the frame that generates the event is active (i.e., for the buttonβs hotkey, how do I only capture the event while the button is on active tab)?
Detail
I am writing a Tkinter application (my first) that uses an object ttk.Notebookto control several parts of the interface. I have several tabs, some of which have the same button on them, but which have different actions, depending on which tab is active (i.e. the "Save" button on one tab saves elements from this tab only , not from all tabs).
An intuitive way to do this is to associate an event with a frame, then a frame containing "active" objects will catch the event, but this does not work. However, if I bind the event to the root window, the same handler is called, regardless of the tab context.
I would have thought that this would be a general requirement, however I cannot find information on how to do this.
I am using Python 3.4.3.
Mcve
, , . , Alt-t, .
import tkinter as tk
from tkinter import ttk
class MyTab(ttk.Frame):
"""Frame to be added to each tab of the notebook.
"""
def __init__(self, master, idx, *args, **kwargs):
super().__init__(master, *args, **kwargs)
self._button = ttk.Button(self, text='Tab {}'.format(idx),
command=lambda *args, x=idx: self._handle_button(x, *args),
underline=0)
self.bind('<Alt-t>', lambda *args, x=idx: self._handle_button(x, *args))
self._button.pack()
self.pack()
def _handle_button(self, x, *args):
print('Button: Tab {}'.format(x))
class MainWdw(ttk.Frame):
"""Main application window.
"""
def __init__(self, master, *args, **kwargs):
super().__init__(master, *args, **kwargs)
self._nb = ttk.Notebook(self)
self._tabs = []
for x in range(1, 6):
t = MyTab(self, x)
self._tabs.append(t)
self._nb.add(t, text='Tab {}'.format(x))
self._nb.pack(expand=1, fill='both')
master.title('Sample')
self.pack(expand=1, fill='both', padx=2, pady=2)
def main():
root = tk.Tk()
app = MainWdw(root)
root.mainloop()
if __name__ == '__main__':
main()