Python GTK: How to set up gtk.Notebook tab with custom widget

Articles may may have files attached at the end of the post

gtk.Notebook is a great feature as it help keep your application footprint on the desktop occupation low. I personnally would not even think of using a web brower without a tab feature as it would take me a help of a time to go from one application to another.

A gtk.Notebook page is composed of a child widget and a label gtk.Widget. From there on, we can fit anything we like in a tab label such as an icon on the side representing the content, a title and a handy close button on the right side a bit like firefox's tabs.

This tutorial will detail how to customize the content of a Notebook tab label but really is a kickstart to any plausible gui arrangement.

Customized GTK Notebook tabsCustomized GTK Notebook tabsBy running the code below, you will get the window shown in the image.

The tab label is composed of an HBox to hold the 3 components: the gtk.Image, the gtk.Label and the gtk.Button.

The close icon will be connected to the clicked event and link to a callback that will handle the closing of the tab.

Here is the code that get to this result:

  1. #!/usr/bin/env python
  2.  
  3. import gtk
  4. import sys
  5.  
  6. #global variables
  7. window = None
  8. notebook = None
  9.  
  10. class MyNotebook(gtk.Notebook):
  11.  
  12.   def __init__(self):
  13.     gtk.Notebook.__init__(self)
  14.     #set the tab properties
  15.     self.set_property('homogeneous', True)
  16.     #we do not show the tab if there is only one tab i total
  17.     self.set_property('show-tabs', False)
  18.  
  19.   def new_tab(self):
  20.     #we create a "Random" image to put in the tab
  21.     icons = [gtk.STOCK_ABOUT, gtk.STOCK_ADD, gtk.STOCK_APPLY, gtk.STOCK_BOLD]
  22.     image = gtk.Image()
  23.     nbpages = self.get_n_pages()
  24.     icon = icons[nbpages%len(icons)]
  25.     image.set_from_stock(icon, gtk.ICON_SIZE_DIALOG)
  26.     self.append_page(image)
  27.    
  28.     #we want to show the tabs if there is more than 1
  29.     if nbpages + 1 > 1:
  30.       self.set_property('show-tabs', True)
  31.     #creation of a custom tab. the left image and
  32.     #the title are made of the stock icon name
  33.     #we pass the child of the tab so we can find the
  34.     #tab back upon closure
  35.     label = self.create_tab_label(icon, image)
  36.     label.show_all()
  37.    
  38.     self.set_tab_label_packing(image, True, True, gtk.PACK_START)
  39.     self.set_tab_label(image, label)
  40.     image.show_all()
  41.     self.set_current_page(nbpages)
  42.  
  43.   def create_tab_label(self, title, tab_child):
  44.     box = gtk.HBox()
  45.     icon = gtk.Image()
  46.     icon.set_from_stock(title, gtk.ICON_SIZE_MENU)
  47.     label = gtk.Label(title)
  48.     closebtn = gtk.Button()
  49.     #the close button is made of an empty button
  50.     #where we set an image
  51.     image = gtk.Image()
  52.     image.set_from_stock(gtk.STOCK_CLOSE, gtk.ICON_SIZE_MENU)
  53.     closebtn.connect("clicked", self.close_tab, tab_child)
  54.     closebtn.set_image(image)
  55.     closebtn.set_relief(gtk.RELIEF_NONE)
  56.     box.pack_start(icon, False, False)
  57.     box.pack_start(label, True, True)
  58.     box.pack_end(closebtn, False, False)
  59.     return box
  60.  
  61.   def close_tab(self, widget, child):
  62.     pagenum = self.page_num(child)
  63.  
  64.     if pagenum != -1:
  65.       self.remove_page(pagenum)
  66.       child.destroy()
  67.       if self.get_n_pages() == 1:
  68.         self.set_property('show-tabs', False)
  69.  
  70. def on_destroy(win):
  71.   gtk.main_quit()
  72.  
  73. def on_delete_event(widget, event):
  74.   gtk.main_quit()
  75.  
  76. def new_tab(widget):
  77.   notebook.new_tab()
  78.  
  79. if __name__ == '__main__':
  80.  
  81.   window = gtk.Window()
  82.   window.set_title("Custom Gtk.Notebook Tabs example")
  83.   window.resize(600,400)
  84.   box = gtk.VBox()
  85.   button = gtk.Button("New Tab")
  86.   box.pack_start(button,False)
  87.   button.connect("clicked", new_tab)
  88.   notebook = MyNotebook()
  89.   box.pack_start(notebook)
  90.   window.add(box)
  91.   window.connect("destroy", on_destroy)
  92.   window.connect("delete-event", on_delete_event)
  93.   window.show_all()
  94.   gtk.main()
  95.   sys.exit(0)

Now let go over the code and see what happens.

AttachmentSize
gtk-notebook-with-custom-tab.py.txt2.63 KB