[wxPython-users] problems drawing on a DC

Christopher Barker Chris.Barker at noaa.gov
Mon Nov 6 14:39:42 PST 2006


Alun Griffiths wrote:
> I would like to load an image from file, draw on top of the image then =

> display it in a frame.  I based this code on some of the examples in =

> WPIA (rather crudely - apologies to the authors)  but am now totally =

> confused about DC's, panels, sizers etc.  What I need to do (I think) is
> =

> (a) load the image from file
> (b) create an empty bitmap the same size as the image to use as a buffer
> (c) copy the image to the buffer

You can do that in one step with:

wx.Bitmap(filename)

> (d) draw on the buffer
yes. you need a wxMemoryDC for that.

> (e) copy the buffer to the frame
> (f) redraw (repaint?) the frame

These are one step.

> The code is attached below and the image is (hopefully) attached.  The =

> image loading and display in the frame (which seems to work OK)

It doesn't work for me.
>         # Create panel to hold sizer
>         self.panel =3D wx.Panel(self)

you'd be better off making that Panel it's own subclass, that does all =

the drawing, etc. then put it on the MainFrame as you need to.

>     def InitBuffer(self):
>         img =3D wx.Image('structure_map.jpg', wx.BITMAP_TYPE_JPEG)
>         bmp =3D wx.StaticBitmap(self.panel, wx.ID_ANY, img.ConvertToBitma=
p())

this could be:
           buffer =3D wx.Bitmap('structure_map.jpg')

>         dc =3D wx.BufferedDC(None, self.buffer)
> =

>         # Draw the wells
> =

>         dc.SetPen(wx.Pen('red'))
> =

>         for well in self.data.wells:
> =

>             # Convert from UTMs to pixels
> =

>             x =3D int( 0.0566 * well.xp - 28175 )
>             y =3D int(-0.0567 * well.yp + 533462)
> =

>             dc.DrawCircle(x, y, 10)
>             dc.DrawText(well.name, x+8, y+8)
> =

>         # Draw the platforms
>         dc.SetPen(wx.Pen('green'))
> =

>         for plat in self.data.platforms:
> =

>             # Convert from UTMs to pixels
> =

>             x =3D int( 0.0566 * plat.xp - 28175)
>             y =3D int(-0.0567 * plat.yp + 533462)
> =

>             dc.DrawRectangle(x-3, y-3, 6, 6)
>             dc.DrawText(plat.name, x+8, y+8)
> =

>         return bmp
> =

> =

>     # Copy from buffer to screen
> =

>     def OnPaint(self, event):
>         dc =3D wx.BufferedPaintDC(self, self.buffer)

Here's your problem. You have a StaticBitmap with the image, then you =

try to draw directly on the Frame. you have two choices:

Change the bitmap in the StaticBitmap with =

StaticBitmap.SetBitmapLabel(), or don't use a Staticbitmap at all, and =

do the drawing in OnPaint, but in this case you want to draw on the =

Panel, not the Frame, so you want to catch its Paint event (which is why =

you should use a subclass of a Panel to do it. all in.

Take a look at the DoubleBuffer demo in the Wiki for an explanation of =

how all this works.

Also, take a look at wx.lib.floatcanvas -- it could do a lot of this for =

you, and give you zooming and panning to boot. Let me know if you want =

the latest version, and some additional demos. AS it happens, I'm using =

FloatCanvas for project now that is similar -- a base map that is a =

geo-referenced image, and drawing an interacting with objects drawn on top.

I've enclosed a re-writing of your code that works and uses some of =

these ideas.

-Chris

-- =

Christopher Barker, Ph.D.
Oceanographer
                                     		=

NOAA/OR&R/HAZMAT         (206) 526-6959   voice
7600 Sand Point Way NE   (206) 526-6329   fax
Seattle, WA  98115       (206) 526-6317   main reception

Chris.Barker at noaa.gov
-------------- next part --------------
A non-text attachment was scrubbed...
Name: junk.py
Type: text/x-python
Size: 5691 bytes
Desc: not available
Url : http://lists.wxwidgets.org/pipermail/wxpython-users/attachments/20061=
106/301510fa/junk.py


More information about the wxpython-users mailing list