title: TTK Notebook Tab Closing Methods
body: <p>I have a TTK Notebook where tabs have close buttons on them, similar to how internet browser tabs have close buttons, but I want to be able to bind a custom method to the individual close buttons so I can display a prompt such as 'Do you wish to save before closing' or 'Are you sure you wish to close this tab?' depending on the tab that was closed. </p>
  
  <p>The problem I am having is that I am unsure how I can create custom closing methods for the individual buttons, as while it's possible to make a generalized yes/no prompt with tkMessageBox, I am unsure of how I can create idiosyncratic methods for each tab. </p>
  
  <p>For example, a form would have an individualized method asking the user whether they would like to save changes made, which would then call the appropriate methods for saving the form, whereas a general tab would probably have no methods relating to when it was closed at all.</p>
  
  <p>The code I am currently using to create close buttons on my tabs is below:</p>
  
  <pre><code>try:
      import Tkinter as tk
      import ttk
  except ImportError:  # Python 3
      import tkinter as tk
      from tkinter import ttk
  
  class CustomNotebook(ttk.Notebook):
      """A ttk Notebook with close buttons on each tab"""
      __initialized = False
  
      def __init__(self, *args, **kwargs):
          if not self.__initialized:
              self.__initialize_custom_style()
              self.__inititialized = True
  
          kwargs["style"] = "CustomNotebook"
          ttk.Notebook.__init__(self, *args, **kwargs)
  
          self._active = None
  
          self.bind("&lt;ButtonPress-1&gt;", self.on_close_press, True)
          self.bind("&lt;ButtonRelease-1&gt;", self.on_close_release)
  
      def on_close_press(self, event):
          """Called when the button is pressed over the close button"""
  
          element = self.identify(event.x, event.y)
  
          if "close" in element:
              index = self.index("@%d,%d" % (event.x, event.y))
              self.state(['pressed'])
              self._active = index
  
      def on_close_release(self, event):
          """Called when the button is released over the close button"""
          if not self.instate(['pressed']):
              return
  
          element =  self.identify(event.x, event.y)
          index = self.index("@%d,%d" % (event.x, event.y))
  
          if "close" in element and self._active == index:
              self.forget(index)
              self.event_generate("&lt;&lt;NotebookTabClosed&gt;&gt;")
  
          self.state(["!pressed"])
          self._active = None
  
      def __initialize_custom_style(self):
          style = ttk.Style()
          self.images = (
              tk.PhotoImage("img_close", data='''
              R0lGODlhCAAIAMIBAAAAADs7O4+Pj9nZ2Ts7Ozs7Ozs7Ozs7OyH+EUNyZWF0ZWQg
              d2l0aCBHSU1QACH5BAEKAAQALAAAAAAIAAgAAAMVGDBEA0qNJyGw7AmxmuaZhWEU
              5kEJADs=
              '''),
              tk.PhotoImage("img_closeactive", data='''
              R0lGODlhCAAIAMIEAAAAAP/SAP/bNNnZ2cbGxsbGxsbGxsbGxiH5BAEKAAQALAAA
              AAAIAAgAAAMVGDBEA0qNJyGw7AmxmuaZhWEU5kEJADs=
              '''),
              tk.PhotoImage("img_closepressed", data='''
              R0lGODlhCAAIAMIEAAAAAOUqKv9mZtnZ2Ts7Ozs7Ozs7Ozs7OyH+EUNyZWF0ZWQg
              d2l0aCBHSU1QACH5BAEKAAQALAAAAAAIAAgAAAMVGDBEA0qNJyGw7AmxmuaZhWEU
              5kEJADs=
          ''')
      )
  
          style.element_create("close", "image", "img_close",
                          ("active", "pressed", "!disabled", "img_closepressed"),
                          ("active", "!disabled", "img_closeactive"), border=8, sticky='')
          style.layout("CustomNotebook", [("CustomNotebook.client", {"sticky": "nswe"})])
          style.layout("CustomNotebook.Tab", [
          ("CustomNotebook.tab", {
              "sticky": "nswe", 
              "children": [
                  ("CustomNotebook.padding", {
                      "side": "top", 
                      "sticky": "nswe",
                      "children": [
                          ("CustomNotebook.focus", {
                              "side": "top", 
                              "sticky": "nswe",
                              "children": [
                                  ("CustomNotebook.label", {"side": "left", "sticky": ''}),
                                  ("CustomNotebook.close", {"side": "left", "sticky": ''}),
                              ]
                      })
                  ]
              })
          ]
      })
  ])
  if __name__ == "__main__":
      root = tk.Tk()
      notebook = CustomNotebook(width=200, height=200)
      notebook.pack(side="top", fill="both", expand=True)
      for color in ("red", "orange", "green", "blue", "violet"):
          frame = tk.Frame(notebook, background=color)
          notebook.add(frame, text=color)
      root.mainloop()
  </code></pre>