The WorkingWithToolBars demo uses embedded button graphics generated from an old version of [ ] found in the .../wx/tools/ directory ( ...\wx\tools folder ). An updated version is now available.

Here's a simplified toolbar demo that uses the embedded graphics :


I call any embedded image data file a "PyImages" file. Creating a brand new PyImages file from any number of disk graphics files is very straightforward. I could have used [ ], but I wrote a much more flexible utilities and Besides, crashes under Win7 as of 2012-04-26 when feeding it more than just several image filenames.

A sample run :

python.exe  Hand.png  Minus.png  Plus.png  Separator.png

Note that the command line arguments may be given in any order.

Hand.png Minus.png Plus.png Separator.png

The utility's execution produces these messages :


You might be wondering what use is the additional utility Running this app with the same command line arguments given to [ ] produces the same pyImages file, but outputs its info in a wxPython GUI. It is just a pretty display for output messages

python.exe  Hand.png  Minus.png  Plus.png  Separator.png

Progress and action messages are emitted by default and are shown in the textCtrl pane. Additional message types must be turned on with their appropriate command-line switches (-f, -n, -w). If there had been any failure or error messages they would have been displayed in an additional right side pane. This simple GUI utility, a work-in-progress, demonstrates how can be called within another app.


If there had been any FAILUREmessages a second TextCtrl named "Failed Operations" would have been added below the "Successful Operations" listing.

To retrieve and use pyImages file graphics data in an app such as :

   1 import wx
   2 import EmbeddedGraphicData as egd
   3     ...
   4 app = wx.App( redirect=False )
   5     ...
   6         tb.AddTool( btnId, egd.GetBitmap_Plus_png(), isToggle=True )
   7         self.Bind( wx.EVT_TOOL, self.OnCustomButton, id=btnId )

Another improvement to the modified toolbar demo is how the event IDs for the button handlers are stored and retrieved. There is never a need to know the values if the IDs, themselves, much less manually assign them. It is enough to know that they all have been uniquely created using calls to wx.NewId(). The custom toolbar button IDs are stored in a small dictionary along with their text message strings that are printed out when the buttons are clicked.

   1         # Create a small dictionary to hold the button IDs and associated text strings.
   2         self.btnDict = dict()
   4         # Add a dictionary key-value pair entry for the "Zoom In" button.
   5         btnId = wx.NewId()
   6         # Create a dictionary entry.
   7         self.btnDict[ btnId ] = 'Mode set to Zoom In the Frame'
   8         # Create a new toolbar custom bitmapped button and associate its event handler.
   9         tb.AddTool( btnId, egd.GetBitmap_Plus_png(), isToggle=True )
  10         self.Bind( wx.EVT_TOOL, self.OnCustomButton, id=btnId )
  12         btnId = wx.NewId()
  13         self.btnDict[ btnId ] = 'Mode set to Zoom Out in the Frame'
  14         tb.AddTool( btnId, egd.GetBitmap_Minus_png(), isToggle=True )
  15         self.Bind( wx.EVT_TOOL, self.OnCustomButton, id=btnId )
  17         btnId = wx.NewId()
  18         self.btnDict[ btnId ] = 'Mode set to Move in the Frame'
  19         tb.AddTool( btnId, egd.GetBitmap_Hand_png(), isToggle=True )
  20         self.Bind( wx.EVT_TOOL, self.OnCustomButton, id=btnId )
  22         tb.AddSeparator()
  24         btnId = wx.NewId()
  25         self.btnDict[ btnId ] = 'Test button clicked'
  26         testBtn = wx.Button( tb, btnId, 'Test' )
  27         tb.AddControl( testBtn )
  28         self.Bind( wx.EVT_BUTTON, self.OnTestButton, id=btnId )

All three custom toolbar buttons use a single event handler. No loop code is necessary for the handle to figure out which to message to print for the particular button event event.

   1     def OnCustomButton( self, event ) :
   3         # Deselect all three buttons which deselects whichever button was previously clicked.
   4         for btnId in self.btnDict.iterkeys() :  # Deselect all buttons including those not now selected.
   5             self.ToolBar.ToggleTool( btnId, 0 )
   7         eventId = event.GetId()      # Which button click caused this event ?
   8         self.ToolBar.ToggleTool( eventId, 1 )   # Show the associated button as being selected.
   9         # Use the ID value as the dictionary's key value to extract the proper text message string.
  10         print self.btnDict[ eventId ]           # Extract and print the proper text message.
  12     #end def
  14     def OnTestButton( self, event ) :    # Only the wxButton could have caused this event.
  15         print self.btnDict[ event.GetId() ]   # The dictionary value is the text message.

The PyImages File Format

This is a portion of the pyImages graphics library data file :

   1 #---------------------------------------------------------------------
   3 # This file was generated by
   5 from wx.lib.embeddedimage import PyEmbeddedImage
   7 catalog = {}
   8 #---------------------------------------------------------------------
  10 Separator_png = PyEmbeddedImage(
  12     "QVQImWP8z8DAwMDAxDB4KACeEAEpN+6uywAAAABJRU5ErkJggg=="
  13     )
  15 catalog["Separator.png"] = "Separator_png"
  16 GetData_Separator_png   = Separator_png.GetData
  17 GetImage_Separator_png  = Separator_png.GetImage
  18 GetBitmap_Separator_png = Separator_png.GetBitmap
  19 GetIcon_Separator_png   = Separator_png.GetIcon

When this file is imported all these Python/wxPython statements are interpreted. The "catalog" dictionary keys are the basenames of the files from which the graphics data were originally extracted using The "Get_()" functions are intended be called inside an app to retrieve the graphics in the data format of choice. Only wxIcon and wxBitmap objects can be directly displayed, but the other functions can be useful depending on your needs. To recreate the disk file "Separator.png" from this pyImages file :

   1 import wx
   2 from EmbeddedGraphicData import *         # This is one of the very, VERY few appropriate uses of "import *".
   4 myNonGUIapp = wx.App( redirect=False )        # Be able to call all wx functions without using a GUI or running MainLoop().
   6 sepBmap = GetBitmap_Separator_png()          # wxBitmap object sepBmap can be used later, if desired
   7 sepBmap.SaveFile ( 'Separator.png', wx.BITMAP_TYPE_PNG )

The code can be shortened a bit without unnecessary codeing obfuscation by combining the calls into a single statement :

   1 import wx
   2 from EmbeddedGraphicData import *         # This is one of the very, VERY few appropriate uses of "import *".
   4 myNonGUIapp = wx.App( redirect=False )        # Be able to call all wx functions without using a GUI and running MainLoop().
   6 GetBitmap_Separator_png().SaveFile ( 'Separator.png', wx.BITMAP_TYPE_PNG )

There will be a problem if two or more pyImage files are imported that both have an image generated from different files with the same basename. This will import two functions with the very same name, the second definition replacing the first. Make sure your disk image filenames are unique to prevent this problem.

PyImages files are also great for holding images for displaying an organization's logo and other decorative artwork using a StaticBitmap.

I hope you find these two utilities useful. - Ray Pasco 2012-05-01

Here's an app with a nice little text editor incorporating a button toolbar. All the embedded icon code is already in this single-file app. The icons you see were pulled from very large "icons" images on the internet, reduced in size and cleaned up with Photoshop. Icons are supposed to be small, otherwise they're not really icons, just images,

The app's right-hand pane is meant to be stuffed with all the controls you would need for your custom app that needs a built-in text editor.

I'll be using the EditorPanel class to develop my own apps. - Ray Pasco 2012-05-04


EmbeddingImagesInSource (last edited 2012-05-04 19:53:01 by pool-71-175-100-238)

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