Introduction

wxPython provides limited tools for doing customized drawings. Still, these tools should be good enough for most purposes. The tools provided work with images in a variety of formats, simple line drawing, simple polygon shapes, and text objects. wxPython provides a variety of textures and colors that can be used as well.

What Objects are Involved

Process Overview

  1. Create a drawing class. This should be something that inherits from wxWindow. For my application, I inherited from a wxPanel. Don't plan on using this class for anything besides the drawing.
  2. Decide how you'll trigger an update to your class. I respond to size events (EVT_SIZE) and paint events (EVT_PAINT). In addition, I design the methods that respond to both of these so they can run if no event is passed--just define your handler as

       def OnSize(self, event=None):

    to allow a call of self.OnSize().

    For paint event handlers you can do something similar but you need to be able to use a different DC since wxPaintDC can only be used from within an EVT_PAINT event. For example:

       1     def OnPaint(self, event):
       2         dc = wxPaintDC(self)
       3         self.DoDrawing(dc)
       4 
       5     def DoDrawing(self, dc=None):
       6         if dc is None:
       7             dc = wxClientDC(self)
       8 
       9         # do the actual drawing here
    
  3. Plan on responding to paint events. If the window gets hidden (for instance, a dialog pops up indicating that "You have mail"...), even briefly, the screen gets blanked. The operating system sends a "paint" event to the window, which is supposed to take care of redrawing itself.
  4. Decide which device contexts you intend to support. Possible contexts are:
    • wxPaintDC -- Plan to support this one. It's a device context that's only appropriate to use within the client area of the widget, and only when called from a paint event. The OS may call this one, so it should be supported.
    • wxClientDC -- Just like a paint context, this alternate device context only allows drawing in the client area of the widget. However, this one is only called when NOT in a paint event. This means that it's NOT called by the OS, but it MAY be called by you when you don't particularly want to wait for a paint event.
    • wxScreenDC -- a device context that allows you to draw anywhere on the screen -- inside a window or not. This could potentially be useful for doing full-screen drawing, such as displaying movies, games, or presentations. I haven't played with this one, so you'll have to decide if it's appropriate and useful for your purposes on your own.
    • wxPrintDC -- a device context corresponding to a printer page. This is part of the printing framework. If you plan to support printing, this is the way to do it. As long as everything you intend to print is drawn to a device context anyway, adding support for printing is easy. Make your print event get a wxPrintDC, then draw to that. You'll get printout virtually for free.
    • wxMemoryDC -- a device context with no visible display. This is useful to provide an off-screen location for image preparation. When the image is ready, you simply copy from the memory DC to the other DC that you're using, and the image is updated instantly and without flicker.
  5. Define your event routines to select the appropriate device context. Once it's selected, call your drawing routines, passing in the selected context.

Obtaining an Appropriate Device Context

As I get time, I'll update this to cover all of these topics.

Loading an initial image

Selecting drawing tools

Adding text to your drawings

Flicker-Free Drawing

Use info from this article: http://freespace.virgin.net/james.brown7/tuts/flicker.htm (see web archive)

See also FlickerFreeDrawing at wxWidgets.

Avoiding unneeded redraws

Double-buffering to eliminate flicker

Printing the results

Adding a print preview

Saving the resulting image

Special Concerns

Transparency and Images/Pens/Brushes

Code Sample

from wxPython.wx import *

CustomisedDrawing (last edited 2008-03-11 10:50:23 by localhost)

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