Quantcast
Channel: Planet Python
Viewing all articles
Browse latest Browse all 22462

Mike Driscoll: wxPython’s Context Managers

$
0
0

The wxPython toolkit added context managers to its code base a few years ago, but for some reason you don’t see very many examples of their use. In this article, we’ll look at three examples of context managers in wxPython. A wxPython user was the first person to suggest using context managers in wxPython on the wxPython mailing list. We’ll start off by rolling our own context manager and then look at a couple of examples of built-in context managers in wxPython.


Creating Your Own wxPython Context Manager

Creating your own context manager in wxPython is pretty easy. We will use the wx.FileDialog for our example of a context manager.

importosimport wx
 
 
########################################################################class ContextFileDialog(wx.FileDialog):
    """""" 
    #----------------------------------------------------------------------def __enter__(self):
        """"""returnself 
    def __exit__(self, exc_type, exc_val, exc_tb):
        self.Destroy() 
 
########################################################################class MyPanel(wx.Panel):
    """""" 
    #----------------------------------------------------------------------def__init__(self, parent):
        """Constructor"""
        wx.Panel.__init__(self, parent) 
        btn = wx.Button(self, label='Open File')
        btn.Bind(wx.EVT_BUTTON, self.onOpenFile) 
    #----------------------------------------------------------------------def onOpenFile(self, event):
        """"""
        wildcard = "Python source (*.py)|*.py|" \
            "All files (*.*)|*.*"
        kwargs = {'message':"Choose a file",
                  'defaultDir':os.path.dirname(os.path.abspath( __file__ )), 
                  'defaultFile':"",
                  'wildcard':wildcard,
                  'style':wx.OPEN | wx.MULTIPLE | wx.CHANGE_DIR}
        with ContextFileDialog(self, **kwargs) as dlg:
            if dlg.ShowModal() == wx.ID_OK:
                paths = dlg.GetPaths()print"You chose the following file(s):"for path in paths:
                    print path
 
 
########################################################################class MyFrame(wx.Frame):
    """""" 
    #----------------------------------------------------------------------def__init__(self):
        """Constructor"""
        wx.Frame.__init__(self, None, title='wxPython Contexts')
        panel = MyPanel(self)self.Show() 
if __name__ == '__main__':
    app = wx.App(False)
    frame = MyFrame()
    app.MainLoop()

In this example, we subclass wx.FileDialog and all we do is override the __enter__ and __exit__ methods. This will turn our FileDialog instance into a context manager when we call it using Pythons with statement. You can see this in the onOpenFile event handler within the MyPanel class. Now let’s move on and look at some of wxPython’s builtin examples!


wxPython’s Context Managers

The wxPython package supports context managers in anything that subclasses wx.Dialog as well as the following widgets:

  • wx.BusyInfo
  • wx.BusyCursor
  • wx.WindowDisabler
  • wx.LogNull
  • wx.DCTextColourChanger
  • wx.DCPenChanger
  • wx.DCBrushChanger
  • wx.DCClipper
  • wx.Freeze / wx.Thaw

There are probably more widgets, but this was the only listing I could find at the time of writing. Let’s look at a couple examples:

importtimeimport wx
 
########################################################################class MyPanel(wx.Panel):
    """""" 
    #----------------------------------------------------------------------def__init__(self, parent):
        """Constructor"""
        wx.Panel.__init__(self, parent)self.frame = parent
 
        main_sizer = wx.BoxSizer(wx.VERTICAL) 
        dlg_btn = wx.Button(self, label='Open ColorDialog')
        dlg_btn.Bind(wx.EVT_BUTTON, self.onOpenColorDialog)
        main_sizer.Add(dlg_btn, 0, wx.ALL|wx.CENTER) 
        busy_btn = wx.Button(self, label='Open BusyInfo')
        busy_btn.Bind(wx.EVT_BUTTON, self.onOpenBusyInfo)
        main_sizer.Add(busy_btn,0, wx.ALL|wx.CENTER) 
        self.SetSizer(main_sizer) 
 
    #----------------------------------------------------------------------def onOpenColorDialog(self, event):
        """
        Creates and opens the wx.ColourDialog
        """
        with wx.ColourDialog(self) as dlg:
            if dlg.ShowModal() == wx.ID_OK:
                data = dlg.GetColourData()
                color = str(data.GetColour().Get())print'You selected: %s\n'% color
 
    #----------------------------------------------------------------------def onOpenBusyInfo(self, event):
        """
        Creates and opens an instance of BusyInfo
        """
        msg = 'This app is busy right now!'self.frame.Hide()
        with wx.BusyInfo(msg) as busy:
            time.sleep(5)self.frame.Show() 
 
########################################################################class MyFrame(wx.Frame):
    """""" 
    #----------------------------------------------------------------------def__init__(self):
        """Constructor"""
        wx.Frame.__init__(self, None, title='Context Managers')
        panel = MyPanel(self) 
        self.Show() 
#----------------------------------------------------------------------if __name__ == '__main__':
    app = wx.App(False)
    frame = MyFrame()
    app.MainLoop()

In the above code, we have two examples of wxPython’s context managers. The first one is in the onOpenColorDialog event handler. Here we create an instance of wx.ColourDialog and then grab the selected color if the user presses the OK button. The second example is only a bit more complex in that it hides the frame before showing the BusyInfo instance. Frankly, I think this example could be improved a bit by putting the frame’s hiding and showing into the context manager itself, but ‘ll leave that as an exercise for the reader to try out.


Wrapping Up

wxPython’s context managers are quite handy and they’re fun to use. I hope you’ll find yourself using them in your own code sometime soon. Be sure and try out some of the other context managers in wxPython to see if they might suit your code base or just to make your code a little cleaner.


Viewing all articles
Browse latest Browse all 22462

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>