Join Club ShowMeDo to Learn Python!

This series is a part of Club ShowMeDo. Click to learn why you should join our club with a simple monthly subscription.

  • We teach Python and all the cool modules
  • Topics include beginner Python, GUIs, Web and Desktop Apps
  • Long, specially crafted video tutorials just for you
  • Club video tutorials extend our normal Free content
  • Save your time - we've done the research for you
  • Keep your skills up-to-date
  • Learn at your own pace, everything you need is shown to you
  • Over 12 hours of archived material are waiting for you in the club

Name: [002] Ian Ozsvald
Member: 128 months
Authored: 181 videos
Description: I am the co-founder of ShowMeDo (see, author of `The Screencasting Handbook <>`_ and the founder of the professional screencast production company `ProCasts <>`_: .. image:: ...

Add Menus, wx Ids, Binding [ID:528] (4/14)

in series: Build a wxPython Image Viewer

(Showmedo is undergoing major changes. To report any problems viewing the videos please email us and include browser and OS specifics. Cheers - Kyran.)

We add a MenuBar with some Menu items. When adding Menus or other widgets you always have to specify an 'id' and there are multiple (slightly confusing!) ways of creating set our wx Ids we discuss wx's '-1', wx.ID_ANY, wx.NewId() and managing your own Ids. I provide the heuristic of always using '-1' for your Ids unless you need more control.

We test wx's new Id using object.GetId() and we use Wingware's Source Assistant feature to look at some wx help text.

Menus aren't much use if they can't control anything so we move on to using self.Bind(...) to attach a menu event to a function - and we look at what happens if the specified function doesn't exist when we try to Bind to it.

Finally we establish the self.OnExit() method and use self.Destory() to cleanly exit the application. We also look at using 'print' to follow the flow of events in the application.

import wx


class Frame(wx.Frame):
    def __init__(self, parent, id, title):
        style=wx.DEFAULT_FRAME_STYLE ^ (wx.RESIZE_BORDER) # XOR to remove the resizeable border        
        wx.Frame.__init__(self, parent, id, title=title, size=MAIN_WINDOW_DEFAULT_SIZE, style=style)
        self.Center() # open in the centre of the screen
        self.panel = wx.Panel(self)
        self.panel.SetBackgroundColour('White') # make the background of the window white


    def CreateMenuBar(self):
        "Create a menu bar with Open, Exit items"
        menuBar = wx.MenuBar()
        # Tell our Frame about this MenuBar
        menuFile = wx.Menu()
        menuBar.Append(menuFile, '&File')
        # NOTE on wx ids - they're used everywhere, we don't care about them
        # Used to handle events and other things
        # An id can be -1 or wx.ID_ANY, wx.NewId(), your own id
        # Get the id using object.GetId()
        #fileOpenMenuItem = menuFile.Append(-1, '&Open Image', 'Open a picture')
        #print "fileOpenMenuItem.GetId()", fileOpenMenuItem.GetId()
        #self.Bind(wx.EVT_MENU, self.OnOpen, fileOpenMenuItem)

        # add a 'mirror' option, disable it for now
        # we add mirrorMenuItem to self so that we can reference it later
        #self.mirrorMenuItem = menuFile.Append(-1, '&Mirror Image', 'Mirror the image horizontally')
        #self.mirrorMenuItem.Enable(False) # we can't mirror an image until we've loaded one in, so start with 'mirror' disabled
        #self.Bind(wx.EVT_MENU, self.OnMirrorImage, self.mirrorMenuItem)
        # create a menu item for Exit and bind it to the OnExit function
        #exitMenuItem = menuFile.Append(-1, 'E&xit', 'Exit the viewer')        
        #self.Bind(wx.EVT_MENU, self.OnExit, exitMenuItem)
        # add a Help menu with an About item
        #menuHelp = wx.Menu()
        #menuBar.Append(menuHelp, '&Help')
        #helpMenuItem = menuHelp.Append(-1, '&About', 'About screen')
        #self.Bind(wx.EVT_MENU, self.OnAbout, helpMenuItem)

    def OnOpen(self, event):
        print "OnOpen called"
    #def OnExit(self, event):
    #    "Close the application by Destroying the object"
    #    # TRY add in your own print call here
    #    self.Destroy() # SHOW HELP SIDEBAR
class App(wx.App):
    def OnInit(self):
        self.frame = Frame(parent=None, id=-1, title='Image Viewer')
        return True
if __name__ == "__main__":       
    # make an App object, set stdout to the console so we can see errors
    app = App(redirect=False)

Got any questions?

Get answers in the ShowMeDo Learners Google Group.

Video statistics:

  • Video's rank shown in the most popular listing
  • Video plays: 0 (since July 30th)
  • Plays in last week: 0
  • Published: 102 months ago

Thank-yous, questions and comments

If this video tutorial was helpful please take some time to say thank-you to the authors for their hard work. Feel free to ask questions. Let the author know why their video tutorial was useful - what are you learning about? Did the video tutorial save you time? Would you like to see more?

You may also want to see our ShowMeDo Google Group to speak to our active users and authors.

Your email address will not be published.

Show some quick comments >>

All comments excluding tick-boxed quick-comments

I had mentioned in an earlier comment I could not see the source code (the code to cut and paste out for my own use). This seems to be an issue when using Internet explorer 7 (on Vista). But switching to firefox the source code section does display. It also displays properly on Opera. I wish I knew why it does not show properly on IE, but that is not a big issue. Really like the video's, speed is fine, I hope you are getting paid by Wingware as you have me thinking about paying for their IDE.

Useful screencast, I think that the event IDs managed by wxpython is a good idea. Worrying about it at beginner fases would be clutering.

It seems my problems have gone away . . . :-)

the code from episode 4 runs just fine.

Great stuff.

Hi Lucas. There was no particular reason, I had refactored the code several times and I think I just missed this one. Out of preference I'd have used 'fileOpenMenuItem' with 'fileExitMenuItem' OR 'openMenuItem' and 'exitMenuItem', but I guess this naming just slipped through.

Well spotted :-)


Hey Ian,

after rewatching this video, I noticed one thing while playing around with the source code:

you named the "Open" item in the "File" menu


The "Exit" item in the same "File" menu is called


The "file" prefix makes sense, it signifies that the menu item is part of the file menu.

Why did you decide not to prefix the "exitMenuItem" menu item?


Good job Ian! This video really repays playing over more than once. I like the way that you are building up the code by assembling the parts and explaining them as you go along. wxPython is a lot more complicated than regular Python, and can be confusing if the viewer tries to take in too much as once. By the way, the viewer should be aware that you can use IPython to supply docstrings:

import wx


(although Wing is more convenient).


This is a great series. Start to finish dev on a simple app.

Looking forward to the next installment.

Video published, thanks for contributing to ShowMeDo

Showmedo is a peer-produced video-tutorials and screencasts site for free and open-source software (FOSS)- with the exception of some club videos, the large majority are free to watch and download.

how to help » about » faq »

Educating the Open-source Community With Showmedo

Although as important as the software it supports, education and documentation are relatively neglected in the Open-source world. Coders love to code, and explaining how best to use or improve the software tends to be deferred or even sidelined.

At Showmedo we believe the community can play a vital role here and also say thanks for the tools and software that make our lives easier. If you have a piece of software you love or a programming langugage you are enthusiastic about, why not make a screencast showing others how to use it? All the stuff you wish you'd been told, the tips, tricks, insights that would have saved you time and frustration.

Screencasting is easier than you think, and we're happy to help you. You can emailus for advice or just use some of the how-to screencasts on the site. This screencasting learning-pathis a good place to start.

Kudos and Thanks for Ian

3 Minute Oveview (What Does Python Look Like?)

simple and informative. you draw me in
70 months ago


Showmedo's development is fairly rapid and bugs will inevitably creep in. If you have any problems please drop us a line using the contact address below. Likewise, any suggestions for improvements to the site are gratefully received.