wx.Treebook

http://www.blog.pythonlibrary.org/wp-content/uploads/2009/12/treebookDemo.png

The Treebook control is a combination of the wx.TreeCtrl and the wx.Notebook. Most TreeCtrls that I’ve seen do not use images, but the wxPython demo uses them for the Treebook, so I decided to use them too. As you can see from the screenshot above, the bitmaps give the Treebook an interesting flavor. Let’s see how to make one of these controls!

   1 import images
   2 import wx
   3  
   4 def getNextImageID(count):
   5     imID = 0
   6     while True:
   7         yield imID
   8         imID += 1
   9         if imID == count:
  10             imID = 0
  11 
  12 ########################################################################
  13 class TabPanel(wx.Panel):
  14     """
  15     This will be the first notebook tab
  16     """
  17     #----------------------------------------------------------------------
  18     def __init__(self, parent):
  19         """"""
  20         
  21         wx.Panel.__init__(self, parent=parent, id=wx.ID_ANY)
  22         
  23         sizer = wx.BoxSizer(wx.VERTICAL)
  24         txtOne = wx.TextCtrl(self, wx.ID_ANY, "")
  25         txtTwo = wx.TextCtrl(self, wx.ID_ANY, "")
  26         
  27         sizer = wx.BoxSizer(wx.VERTICAL)
  28         sizer.Add(txtOne, 0, wx.ALL, 5)
  29         sizer.Add(txtTwo, 0, wx.ALL, 5)
  30         
  31         self.SetSizer(sizer)
  32  
  33 ########################################################################
  34 class TreebookDemo(wx.Treebook):
  35     """
  36     Treebook class
  37     """
  38  
  39     #----------------------------------------------------------------------
  40     def __init__(self, parent):
  41         """Constructor"""
  42         wx.Treebook.__init__(self, parent, wx.ID_ANY, style=
  43                              wx.BK_DEFAULT
  44                              #wx.BK_TOP
  45                              #wx.BK_BOTTOM
  46                              #wx.BK_LEFT
  47                              #wx.BK_RIGHT
  48                             )
  49         il = wx.ImageList(32, 32)
  50         for x in range(6):
  51             obj = getattr(images, 'LB%02d' % (x+1))
  52             bmp = obj.GetBitmap()
  53             il.Add(bmp)
  54         self.AssignImageList(il)
  55         imageIdGenerator = getNextImageID(il.GetImageCount())
  56  
  57         pages = [(panelOne.TabPanel(self), "Panel One"),
  58                  (panelTwo.TabPanel(self), "Panel Two"),
  59                  (panelThree.TabPanel(self), "Panel Three")]
  60         imID = 0
  61         for page, label in pages:
  62             self.AddPage(page, label, imageId=imageIdGenerator.next())
  63             imID += 1
  64             self.AddSubPage(page, 'a sub-page', imageId=imageIdGenerator.next())
  65  
  66         self.Bind(wx.EVT_TREEBOOK_PAGE_CHANGED, self.OnPageChanged)
  67         self.Bind(wx.EVT_TREEBOOK_PAGE_CHANGING, self.OnPageChanging)
  68  
  69         # This is a workaround for a sizing bug on Mac...
  70         wx.FutureCall(100, self.AdjustSize)
  71  
  72     #----------------------------------------------------------------------
  73     def AdjustSize(self):
  74         #print self.GetTreeCtrl().GetBestSize()
  75         self.GetTreeCtrl().InvalidateBestSize()
  76         self.SendSizeEvent()
  77  
  78     #----------------------------------------------------------------------
  79     def OnPageChanged(self, event):
  80         old = event.GetOldSelection()
  81         new = event.GetSelection()
  82         sel = self.GetSelection()
  83         print 'OnPageChanged,  old:%d, new:%d, sel:%d\n' % (old, new, sel)
  84         event.Skip()
  85  
  86     #----------------------------------------------------------------------
  87     def OnPageChanging(self, event):
  88         old = event.GetOldSelection()
  89         new = event.GetSelection()
  90         sel = self.GetSelection()
  91         print 'OnPageChanging, old:%d, new:%d, sel:%d\n' % (old, new, sel)
  92         event.Skip()
  93  
  94 ########################################################################
  95 class DemoFrame(wx.Frame):
  96     """
  97     Frame that holds all other widgets
  98     """
  99  
 100     #----------------------------------------------------------------------
 101     def __init__(self):
 102         """Constructor"""
 103         wx.Frame.__init__(self, None, wx.ID_ANY,
 104                           "Treebook Tutorial",
 105                           size=(700,400)
 106                           )
 107         panel = wx.Panel(self)
 108  
 109         notebook = TreebookDemo(panel)
 110         sizer = wx.BoxSizer(wx.VERTICAL)
 111         sizer.Add(notebook, 1, wx.ALL|wx.EXPAND, 5)
 112         panel.SetSizer(sizer)
 113         self.Layout()
 114  
 115         self.Show()
 116  
 117 #----------------------------------------------------------------------
 118 if __name__ == "__main__":
 119     app = wx.PySimpleApp()
 120     frame = DemoFrame()
 121     app.MainLoop()

As with the Toolbook, I once again used a some code from the wxPython demo to create this demo and reused some of my own “framework” code. Besides the specialized events of the Treebook, you should also take note that it has an AddSubPage method, which adds a sub-node to the tree which in turn adds another page to the notebook. There are several other methods that only this control has: CollapseNode, ExpandNode, GetPageParent, GetTreeCtrl, InsertSubPage and IsNodeExpanded. I think they’re pretty self-explanatory, but don’t be afraid to read the documentation.

All code was tested on the following:

For Further Information

Note: The tutorial on this page is a modified version of the tutorial on my blog

Treebook (last edited 2009-12-13 19:32:43 by 208)

NOTE: To edit pages in this wiki you must be a member of the TrustedEditorsGroup.