10.12. Notebooks

The NoteBook Widget is a collection of "pages" that overlap each other, each page contains different information with only one page visible at a time. This widget has become more common lately in GUI programming, and it is a good way to show blocks of similar information that warrant separation in their display.

The first function call you will need to know, as you can probably guess by now, is used to create a new notebook widget.
 
notebook = GtkNotebook()

Once the notebook has been created, there are a number of methods that operate on the notebook widget. Let's look at them individually.

The first one we will look at is how to position the page indicators. These page indicators or "tabs" as they are referred to, can be positioned in four ways: top, bottom, left, or right.
 
notebook.set_tab_pos(pos)

GtkPositionType will be one of the following, which are pretty self explanatory:
 
  POS_LEFT
  POS_RIGHT
  POS_TOP
  POS_BOTTOM

POS_TOP is the default.

Next we will look at how to add pages to the notebook. There are three ways to add pages to the NoteBook. Let's look at the first two together as they are quite similar.
 
notebook.append_page(child, tab_label)

notebook.prepend_page(child, tab_label)

These methods add pages to the notebook by inserting them from the back of the notebook (append), or the front of the notebook (prepend). child is the widget that is placed within the notebook page, and tab_label is the label for the page being added. The child widget must be created separately, and is typically a set of options setup within one of the other container widgets, such as a table.

The final method for adding a page to the notebook contains all of the properties of the previous two, but it allows you to specify what position you want the page to be in the notebook.
 
notebook.insert_page(child, tab_label, position)

The parameters are the same as append() and prepend() except it contains an extra parameter, position. This parameter is used to specify what place this page will be inserted into; the first page having position zero.

Now that we know how to add a page, lets see how we can remove a page from the notebook.
 
notebook.remove_page(page_num)

This method takes the page specified by page_num and removes it from the widget pointed to by notebook.

To find out what the current page is in a notebook use the method:
 
page = notebook.get_current_page()

These next two methods are simple calls to move the notebook page forward or backward. Simply provide the respective method call with the notebook widget you wish to operate on. Note: When the NoteBook is currently on the last page, and next_page() is called, the notebook will wrap back to the first page. Likewise, if the NoteBook is on the first page, and prev_page() is called, the notebook will wrap to the last page.
 
notebook.next_page()
notebook.prev_page()

This next method sets the "active" page. If you wish the notebook to be opened to page 5 for example, you would use this method. Without using this method, the notebook defaults to the first page.
 
notebook.set_page(page_num)

The next two methods add or remove the notebook page tabs and the notebook border respectively.
 
notebook.set_show_tabs(show_tabs)

notebook.set_show_border(show_border)

The next method is useful when the you have a large number of pages, and the tabs don't fit on the page. It allows the tabs to be scrolled through using two arrow buttons.
 
notebook.set_scrollable(scrollable)

show_tabs, show_border and scrollable can be either TRUE or FALSE.

Now let's look at an example, it is expanded from the testgtk.py code that comes with the PyGTK distribution. The notebook.py program creates a window with a notebook and six buttons. The notebook contains 11 pages, added in three different ways, appended, inserted, and prepended. The buttons allow you rotate the tab positions, add/remove the tabs and border, remove a page, change pages in both a forward and backward manner, and exit the program. Figure 10.10 illustrates the program display:

Figure 10.10 Notebook Example

The source code for notebook.py is:
 
    1   #!/usr/bin/env python
    2   
    3   # example notebook.py
    4   
    5   import gtk
    6   
    7   class NotebookExample:
    8       # This method rotates the position of the tabs
    9       def rotate_book(self, button, notebook):
   10           notebook.set_tab_pos((notebook.get_tab_pos()+1) %4)
   11   
   12       # Add/Remove the page tabs and the borders
   13       def tabsborder_book(self, button, notebook):
   14           tval = gtk.FALSE
   15           bval = gtk.FALSE
   16           if self.show_tabs == gtk.FALSE:
   17               tval = gtk.TRUE 
   18           if self.show_border == gtk.FALSE:
   19               bval = gtk.TRUE
   20   
   21           notebook.set_show_tabs(tval)
   22           self.show_tabs = tval
   23           notebook.set_show_border(bval)
   24           self.show_border = bval
   25   
   26       # Remove a page from the notebook
   27       def remove_book(self, button, notebook):
   28           page = notebook.get_current_page()
   29           notebook.remove_page(page)
   30           # Need to refresh the widget -- 
   31           # This forces the widget to redraw itself.
   32           notebook.draw((0,0,-1,-1))
   33   
   34       def delete(self, widget, event=None):
   35           gtk.mainquit()
   36           return gtk.FALSE
   37   
   38       def __init__(self):
   39           window = gtk.GtkWindow(gtk.WINDOW_TOPLEVEL)
   40           window.connect("delete_event", self.delete)
   41           window.set_border_width(10)
   42   
   43           table = gtk.GtkTable(3,6,gtk.FALSE)
   44           window.add(table)
   45   
   46           # Create a new notebook, place the position of the tabs
   47           notebook = gtk.GtkNotebook()
   48           notebook.set_tab_pos(gtk.POS_TOP)
   49           table.attach(notebook, 0,6,0,1)
   50           notebook.show()
   51           self.show_tabs = gtk.TRUE
   52           self.show_border = gtk.TRUE
   53   
   54           # Let's append a bunch of pages to the notebook
   55           for i in range(5):
   56               bufferf = "Append Frame %d" % (i+1)
   57               bufferl = "Page %d" % (i+1)
   58   
   59               frame = gtk.GtkFrame(bufferf)
   60               frame.set_border_width(10)
   61               frame.set_usize(100, 75)
   62               frame.show()
   63   
   64               label = gtk.GtkLabel(bufferf)
   65               frame.add(label)
   66               label.show()
   67   
   68               label = gtk.GtkLabel(bufferl)
   69               notebook.append_page(frame, label)
   70         
   71           # Now let's add a page to a specific spot
   72           checkbutton = gtk.GtkCheckButton("Check me please!")
   73           checkbutton.set_usize(100, 75)
   74           checkbutton.show ()
   75   
   76           label = gtk.GtkLabel("Add page")
   77           notebook.insert_page(checkbutton, label, 2)
   78   
   79           # Now finally let's prepend pages to the notebook
   80           for i in range(5):
   81               bufferf = "Prepend Frame %d" % (i+1)
   82               bufferl = "PPage %d" % (i+1)
   83   
   84               frame = gtk.GtkFrame(bufferf)
   85               frame.set_border_width(10)
   86               frame.set_usize(100, 75)
   87               frame.show()
   88   
   89               label = gtk.GtkLabel(bufferf)
   90               frame.add(label)
   91               label.show()
   92   
   93               label = gtk.GtkLabel(bufferl)
   94               notebook.prepend_page(frame, label)
   95       
   96           # Set what page to start at (page 4)
   97           notebook.set_page(3)
   98   
   99           # Create a bunch of buttons
  100           button = gtk.GtkButton("close")
  101           button.connect("clicked", self.delete)
  102           table.attach(button, 0,1,1,2)
  103           button.show()
  104   
  105           button = gtk.GtkButton("next page")
  106           button.connect("clicked", notebook.next_page)
  107           table.attach(button, 1,2,1,2)
  108           button.show()
  109   
  110           button = gtk.GtkButton("prev page")
  111           button.connect("clicked", notebook.prev_page)
  112           table.attach(button, 2,3,1,2)
  113           button.show()
  114   
  115           button = gtk.GtkButton("tab position")
  116           button.connect("clicked", self.rotate_book, notebook)
  117           table.attach(button, 3,4,1,2)
  118           button.show()
  119   
  120           button = gtk.GtkButton("tabs/border on/off")
  121           button.connect("clicked", self.tabsborder_book, notebook)
  122           table.attach(button, 4,5,1,2)
  123           button.show()
  124   
  125           button = gtk.GtkButton("remove page")
  126           button.connect("clicked", self.remove_book, notebook)
  127           table.attach(button, 5,6,1,2)
  128           button.show()
  129   
  130           table.show()
  131           window.show()
  132   
  133   def main():
  134       gtk.mainloop()
  135       return 0
  136   
  137   if __name__ == "__main__":
  138       NotebookExample()
  139       main()

I hope this helps you on your way with creating notebooks for your PyGTK applications.