wx.Toolbook
The Toolbook is a wx.Toolbar plus a wx.Notebook, which means that you use labeled bitmap buttons to control which “tab” of the notebook you are viewing. As you probably noticed with the Listbook example, I used the wxPython demo’s “images” module for its images and I use it again in my sample code here.
This first piece will make up the panel that we'll base our tabs on:
1 import wx
2 import wx.lib.mixins.listctrl as listmix
3
4 musicdata = {
5 1 : ("Bad English", "The Price Of Love", "Rock"),
6 2 : ("DNA featuring Suzanne Vega", "Tom's Diner", "Rock"),
7 3 : ("George Michael", "Praying For Time", "Rock"),
8 4 : ("Gloria Estefan", "Here We Are", "Rock"),
9 5 : ("Linda Ronstadt", "Don't Know Much", "Rock"),
10 6 : ("Michael Bolton", "How Am I Supposed To Live Without You", "Blues"),
11 7 : ("Paul Young", "Oh Girl", "Rock"),
12 8 : ("Paula Abdul", "Opposites Attract", "Rock"),
13 9 : ("Richard Marx", "Should've Known Better", "Rock"),
14 10: ("Rod Stewart", "Forever Young", "Rock"),
15 11: ("Roxette", "Dangerous", "Rock"),
16 12: ("Sheena Easton", "The Lover In Me", "Rock"),
17 13: ("Sinead O'Connor", "Nothing Compares 2 U", "Rock"),
18 14: ("Stevie B.", "Because I Love You", "Rock"),
19 15: ("Taylor Dayne", "Love Will Lead You Back", "Rock"),
20 16: ("The Bangles", "Eternal Flame", "Rock"),
21 17: ("Wilson Phillips", "Release Me", "Rock"),
22 18: ("Billy Joel", "Blonde Over Blue", "Rock"),
23 19: ("Billy Joel", "Famous Last Words", "Rock"),
24 20: ("Billy Joel", "Lullabye (Goodnight, My Angel)", "Rock"),
25 21: ("Billy Joel", "The River Of Dreams", "Rock"),
26 22: ("Billy Joel", "Two Thousand Years", "Rock")
27 }
28
29 class TestListCtrl(wx.ListCtrl, listmix.ListCtrlAutoWidthMixin):
30 def __init__(self, parent, ID, pos=wx.DefaultPosition,
31 size=wx.DefaultSize, style=0):
32 wx.ListCtrl.__init__(self, parent, ID, pos, size, style)
33 listmix.ListCtrlAutoWidthMixin.__init__(self)
34
35 class TabPanel(wx.Panel, listmix.ColumnSorterMixin):
36 """
37 This will be the second notebook tab
38 """
39 #----------------------------------------------------------------------
40 def __init__(self, parent):
41 """"""
42 wx.Panel.__init__(self, parent=parent, id=wx.ID_ANY)
43 self.createAndLayout()
44
45 def createAndLayout(self):
46 sizer = wx.BoxSizer(wx.VERTICAL)
47 self.list = TestListCtrl(self, wx.ID_ANY, style=wx.LC_REPORT
48 | wx.BORDER_NONE
49 | wx.LC_EDIT_LABELS
50 | wx.LC_SORT_ASCENDING)
51 sizer.Add(self.list, 1, wx.EXPAND)
52 self.populateList()
53 # Now that the list exists we can init the other base class,
54 # see wx/lib/mixins/listctrl.py
55 self.itemDataMap = musicdata
56 listmix.ColumnSorterMixin.__init__(self, 3)
57 self.SetSizer(sizer)
58 self.SetAutoLayout(True)
59
60 def populateList(self):
61 self.list.InsertColumn(0, "Artist")
62 self.list.InsertColumn(1, "Title", wx.LIST_FORMAT_RIGHT)
63 self.list.InsertColumn(2, "Genre")
64 items = musicdata.items()
65
66 for key, data in items:
67 index = self.list.InsertStringItem(sys.maxint, data[0])
68 self.list.SetStringItem(index, 1, data[1])
69 self.list.SetStringItem(index, 2, data[2])
70 self.list.SetItemData(index, key)
71
72 self.list.SetColumnWidth(0, wx.LIST_AUTOSIZE)
73 self.list.SetColumnWidth(1, wx.LIST_AUTOSIZE)
74 self.list.SetColumnWidth(2, 100)
75
76 # show how to select an item
77 self.list.SetItemState(5, wx.LIST_STATE_SELECTED, wx.LIST_STATE_SELECTED)
78
79 # show how to change the colour of a couple items
80 item = self.list.GetItem(1)
81 item.SetTextColour(wx.BLUE)
82 self.list.SetItem(item)
83 item = self.list.GetItem(4)
84 item.SetTextColour(wx.RED)
85 self.list.SetItem(item)
86
87 self.currentItem = 0
88
89 # Used by the ColumnSorterMixin, see wx/lib/mixins/listctrl.py
90 def GetListCtrl(self):
91 return self.list
Now we can use the panel above for our Toolbook code demo, which is below.
1 import images
2 import wx
3
4 #----------------------------------------------------------------------
5 def getNextImageID(count):
6 imID = 0
7 while True:
8 yield imID
9 imID += 1
10 if imID == count:
11 imID = 0
12
13 ########################################################################
14 class ToolbookDemo(wx.Toolbook):
15 """
16 Toolbook class
17 """
18
19 #----------------------------------------------------------------------
20 def __init__(self, parent):
21 """Constructor"""
22 wx.Toolbook.__init__(self, parent, wx.ID_ANY, style=
23 wx.BK_DEFAULT
24 #wx.BK_TOP
25 #wx.BK_BOTTOM
26 #wx.BK_LEFT
27 #wx.BK_RIGHT
28 )
29
30 # make an image list using the LBXX images
31 il = wx.ImageList(32, 32)
32 for x in range(3):
33 obj = getattr(images, 'LB%02d' % (x+1))
34 bmp = obj.GetBitmap()
35 il.Add(bmp)
36 self.AssignImageList(il)
37 imageIdGenerator = getNextImageID(il.GetImageCount())
38
39 pages = [(panelOne.TabPanel(self), "Panel One"),
40 (panelTwo.TabPanel(self), "Panel Two"),
41 (panelThree.TabPanel(self), "Panel Three")]
42 imID = 0
43 for page, label in pages:
44 self.AddPage(page, label, imageId=imageIdGenerator.next())
45 imID += 1
46
47 self.Bind(wx.EVT_TOOLBOOK_PAGE_CHANGED, self.OnPageChanged)
48 self.Bind(wx.EVT_TOOLBOOK_PAGE_CHANGING, self.OnPageChanging)
49
50 #----------------------------------------------------------------------
51 def OnPageChanged(self, event):
52 old = event.GetOldSelection()
53 new = event.GetSelection()
54 sel = self.GetSelection()
55 print 'OnPageChanged, old:%d, new:%d, sel:%d\n' % (old, new, sel)
56 event.Skip()
57
58 #----------------------------------------------------------------------
59 def OnPageChanging(self, event):
60 old = event.GetOldSelection()
61 new = event.GetSelection()
62 sel = self.GetSelection()
63 print 'OnPageChanging, old:%d, new:%d, sel:%d\n' % (old, new, sel)
64 event.Skip()
65
66 ########################################################################
67 class DemoFrame(wx.Frame):
68 """
69 Frame that holds all other widgets
70 """
71
72 #----------------------------------------------------------------------
73 def __init__(self):
74 """Constructor"""
75 wx.Frame.__init__(self, None, wx.ID_ANY,
76 "Toolbook Tutorial",
77 size=(700,400)
78 )
79 panel = wx.Panel(self)
80
81 notebook = ToolbookDemo(panel)
82 sizer = wx.BoxSizer(wx.VERTICAL)
83 sizer.Add(notebook, 1, wx.ALL|wx.EXPAND, 5)
84 panel.SetSizer(sizer)
85 self.Layout()
86
87 self.Show()
88
89 #----------------------------------------------------------------------
90 if __name__ == "__main__":
91 app = wx.PySimpleApp()
92 frame = DemoFrame()
93 app.MainLoop()
The Toolbook follows in the footsteps of the previous controls as its lineage comes from the wx.BookCtrlBase. This widget’s claim to fame is its look and feel (although it looks very similar to the Listbook) and the Toolbook’s unique events. I used some fun code from the wxPython demo to help in assigning images to the toolbar’s buttons, but that’s really the only difference of any importance. For full disclosure, read the docs for this control!
All code was tested on the following:
- Windows XP, wxPython 2.8.10.1 (unicode), Python 2.5
- Windows Vista, wxPython 2.8.10.1 (unicode), Python 2.5
For Further Information
Note: The tutorial on this page is a modified version of the tutorial on my blog