Wed 9 Dec 2009
The “Book” Controls of wxPython (Part 2 of 2)
Posted by Mike under Cross-Platform, Python, wxPython
[11] Comments
Our next example will be more complex and will show you how to change a few notebook settings.
Listing 5
import panelOne, panelTwo, panelThree import wx import wx.lib.agw.aui as aui ID_NotebookArtGloss = 0 ID_NotebookArtSimple = 1 ID_NotebookArtVC71 = 2 ID_NotebookArtFF2 = 3 ID_NotebookArtVC8 = 4 ID_NotebookArtChrome = 5 ######################################################################## class AUIManager(aui.AuiManager): """ AUI Manager class """ #---------------------------------------------------------------------- def __init__(self, managed_window): """Constructor""" aui.AuiManager.__init__(self) self.SetManagedWindow(managed_window) ######################################################################## class AUINotebook(aui.AuiNotebook): """ AUI Notebook class """ #---------------------------------------------------------------------- def __init__(self, parent): """Constructor""" aui.AuiNotebook.__init__(self, parent=parent) self.default_style = aui.AUI_NB_DEFAULT_STYLE | aui.AUI_NB_TAB_EXTERNAL_MOVE | wx.NO_BORDER self.SetWindowStyleFlag(self.default_style) # add some pages to the notebook pages = [panelOne, panelTwo, panelThree] x = 1 for page in pages: label = "Tab #%i" % x tab = page.TabPanel(self) self.AddPage(tab, label, False) x += 1 ######################################################################## class DemoFrame(wx.Frame): """ wx.Frame class """ #---------------------------------------------------------------------- def __init__(self): """Constructor""" title = "AGW AUI Notebook Feature Tutorial" wx.Frame.__init__(self, None, wx.ID_ANY, title=title, size=(600,400)) self.themeDict = {"Glossy Theme (Default)":0, "Simple Theme":1, "VC71 Theme":2, "Firefox 2 Theme":3, "VC8 Theme":4, "Chrome Theme":5, } # create the AUI manager self.aui_mgr = AUIManager(self) # create the AUI Notebook self.notebook = AUINotebook(self) self._notebook_style = self.notebook.default_style # add notebook to AUI manager self.aui_mgr.AddPane(self.notebook, aui.AuiPaneInfo().Name("notebook_content"). CenterPane().PaneBorder(False)) self.aui_mgr.Update() # create menu and tool bars self.createMenu() self.createTB() #---------------------------------------------------------------------- def createMenu(self): """ Create the menu """ def doBind(item, handler): """ Create menu events. """ self.Bind(wx.EVT_MENU, handler, item) menubar = wx.MenuBar() fileMenu = wx.Menu() doBind( fileMenu.Append(wx.ID_ANY, "&Exit\tAlt+F4", "Exit Program"),self.onExit) optionsMenu = wx.Menu() doBind( optionsMenu.Append(wx.ID_ANY, "Disable Current Tab"), self.onDisableTab) # add the menus to the menubar menubar.Append(fileMenu, "File") menubar.Append(optionsMenu, "Options") self.SetMenuBar(menubar) #---------------------------------------------------------------------- def createTB(self): """ Create the toolbar """ TBFLAGS = ( wx.TB_HORIZONTAL | wx.NO_BORDER | wx.TB_FLAT ) tb = self.CreateToolBar(TBFLAGS) keys = self.themeDict.keys() keys.sort() choices = keys cb = wx.ComboBox(tb, wx.ID_ANY, "Glossy Theme (Default)", choices=choices, size=wx.DefaultSize, style=wx.CB_DROPDOWN) cb.Bind(wx.EVT_COMBOBOX, self.onChangeTheme) tb.AddControl(cb) tb.AddSeparator() self.closeChoices = ["No Close Button", "Close Button At Right", "Close Button On All Tabs", "Close Button On Active Tab"] cb = wx.ComboBox(tb, wx.ID_ANY, self.closeChoices[3], choices=self.closeChoices, size=wx.DefaultSize, style=wx.CB_DROPDOWN) cb.Bind(wx.EVT_COMBOBOX, self.onChangeTabClose) tb.AddControl(cb) tb.Realize() #---------------------------------------------------------------------- def onChangeTabClose(self, event): """ Change how the close button behaves on a tab Note: Based partially on the agw AUI demo """ choice = event.GetString() self._notebook_style &= ~(aui.AUI_NB_CLOSE_BUTTON | aui.AUI_NB_CLOSE_ON_ACTIVE_TAB | aui.AUI_NB_CLOSE_ON_ALL_TABS) # note that this close button doesn't work for some reason if choice == "Close Button At Right": self._notebook_style ^= aui.AUI_NB_CLOSE_BUTTON elif choice == "Close Button On All Tabs": self._notebook_style ^= aui.AUI_NB_CLOSE_ON_ALL_TABS elif choice == "Close Button On Active Tab": self._notebook_style ^= aui.AUI_NB_CLOSE_ON_ACTIVE_TAB self.notebook.SetWindowStyleFlag(self._notebook_style) self.notebook.Refresh() self.notebook.Update() #---------------------------------------------------------------------- def onChangeTheme(self, event): """ Changes the notebook's theme Note: Based partially on the agw AUI demo """ print event.GetString() evId = self.themeDict[event.GetString()] print evId all_panes = self.aui_mgr.GetAllPanes() for pane in all_panes: if isinstance(pane.window, aui.AuiNotebook): nb = pane.window if evId == ID_NotebookArtGloss: nb.SetArtProvider(aui.AuiDefaultTabArt()) self._notebook_theme = 0 elif evId == ID_NotebookArtSimple: nb.SetArtProvider(aui.AuiSimpleTabArt()) self._notebook_theme = 1 elif evId == ID_NotebookArtVC71: nb.SetArtProvider(aui.VC71TabArt()) self._notebook_theme = 2 elif evId == ID_NotebookArtFF2: nb.SetArtProvider(aui.FF2TabArt()) self._notebook_theme = 3 elif evId == ID_NotebookArtVC8: nb.SetArtProvider(aui.VC8TabArt()) self._notebook_theme = 4 elif evId == ID_NotebookArtChrome: nb.SetArtProvider(aui.ChromeTabArt()) self._notebook_theme = 5 #nb.SetWindowStyleFlag(self._notebook_style) nb.Refresh() nb.Update() #---------------------------------------------------------------------- def onDisableTab(self, event): """ Disables the current tab """ page = self.notebook.GetCurrentPage() page_idx = self.notebook.GetPageIndex(page) self.notebook.EnableTab(page_idx, False) self.notebook.AdvanceSelection() #---------------------------------------------------------------------- def onExit(self, event): """ Close the demo """ self.Close() #---------------------------------------------------------------------- if __name__ == "__main__": app = wx.PySimpleApp() frame = DemoFrame() frame.Show() app.MainLoop()
For this demo, I decided to try subclassing AuiManager and the aui.AuiNotebook. While I think this could be helpful if you ever needed to instantiate multiple AuiManager instances, for the purposes of this demo, it really didn’t help much other than showing you how to do it. Let’s unpack this example bit by bit and see how it works!
In the AuiManager class, I force the programmer to pass in the window to be managed and it calls the SetManagedWindow() automatically. You could do this with some of AuiManager’s other functions as well. In the AuiNotebook’s case, I set a default style using its SetWindowStyleFlag() method and then I add some pages to the notebook. This gives me a quick and easy way to create multiple notebooks quickly.
The DemoFrame does the bulk of the work. It creates a theme dictionary for later use, instantiates the AuiManager and AuiNotebook, and creates a toolbar and menubar. Our focus will be the event handlers related to the menubar and the toolbar as they affect the way the AuiNotebook functions. Our first method of interest is onChangeTabClose().
Listing 6
def onChangeTabClose(self, event): """ Change how the close button behaves on a tab Note: Based partially on the agw AUI demo """ choice = event.GetString() self._notebook_style &= ~(aui.AUI_NB_CLOSE_BUTTON | aui.AUI_NB_CLOSE_ON_ACTIVE_TAB | aui.AUI_NB_CLOSE_ON_ALL_TABS) # note that this close button doesn't work for some reason if choice == "Close Button At Right": self._notebook_style ^= aui.AUI_NB_CLOSE_BUTTON elif choice == "Close Button On All Tabs": self._notebook_style ^= aui.AUI_NB_CLOSE_ON_ALL_TABS elif choice == "Close Button On Active Tab": self._notebook_style ^= aui.AUI_NB_CLOSE_ON_ACTIVE_TAB self.notebook.SetWindowStyleFlag(self._notebook_style) self.notebook.Refresh() self.notebook.Update()
This event handler is invoked from combobox events generated by the second combobox in the toolbar. Its purpose is to decide the placement of the close button on the tabs. First, it grabs the user’s choice by calling “event.GetString()”. Next it uses some bitwise operators to clear the close button related styles. If I’m reading it correctly, it “ands” the current notebook style with a “notted” multi-”or”. Yes, it’s confusing. To put it simply, it says that the three styles (aui.AUI_NB_CLOSE_BUTTON, aui.AUI_NB_CLOSE_ON_ACTIVE_TAB, aui.AUI_NB_CLOSE_ON_ALL_TABS) will be subtracted from the current notebook style.
Then I use a conditional to decide which style to actually apply to the notebook. Once that’s added to the variable, I use the notebook’s SetWindowStyleFlag() to apply it and then Refresh and Update the display so the user can see the changes.
-
bc
-
bc
-
http://www.pythonlibrary.org/ mld
-
Anonymous
-
ma
-
ma
-
Anonymous
-
ma
-
Anonymous
-
ma
