[wxPython] Problem saving drawing to a file

I have a version using a memory bitmap that works on windows (It is
attached). I' am going to test this on linux later at home, but I think it
is going to work.
I put all the logical-pixel transform on a wxMemoryDC derived class.

Thanks for the help (Tim and Chris)
Cristian

CerCanvasEN.py (6.52 KB)

···

-----Original Message-----
From: Chris Barker [mailto:Chris.Barker@noaa.gov]
Sent: Thursday, October 24, 2002 2:51 PM
To: wxpython-users@lists.wxwindows.org
Subject: Re: [wxPython] Problem saving drawing to a file

"Echeverria Rabi, Cristián" wrote:

> One alternative is to do ALL your drawing into a memory bitmap
> Do you have a routine that redraws your canvas?

Yes, I think that's the way to go!!

I quickly tried to re-factor your code to use an offscreen bitmap. The
saving ot a file works, but the drawing is somehow wrong. I htink I
messed up your logical-pixel transform somehow. Anyway, here it is, it
might give you some ideas.

-Chris

"Echeverria Rabi, Cristián" wrote:

I have a version using a memory bitmap that works on windows (It is
attached). I' am going to test this on linux later at home, but I think it
is going to work.
I put all the logical-pixel transform on a wxMemoryDC derived class.

Yes, it works on Linux, but I have a couple of suggestions for
improvements. The way you wrote it, the off-screen bitmap works for
creating a buffer for your save to file, but you don't have the other
advantages of double buffering. In yoour OnPaint method, you call
DoBitmapDrawing, so the bitmap gets re-drawn at every OnPaint event,
even though it hasn't changed.

Your OnPaint method should only blit the bitmap to the screen, and the
Drawing calls should only get called when the drawing needs updating.
also, you can blit a bitmap to a dc with the DrawBitmap method. there is
no need to set up a MemDC for that. I've made the changes to the
enclosed version, but here they are:

    def OnPaint(self, event):
        dc = wxPaintDC(self)
        self.PrepareDC(dc)
        #self.DoBitmapDrawing()
        dc.DrawBitmap(self.bitmap,0,0)
  # that's all it takes to do the blit. and you don't need DoDrawing at
all.

# you do need to draw the image sometime, so I do it on initialization:
        
        self.canvas = MyCanvas(self)
        self.canvas.DoBitmapDrawing()

# and when you want to update it:

    def OnDeleteCuad(self,event):
        self.canvas.more_lines = [(1,3),(3,3),(3,1),(1,1),(1,3)]
        self.canvas.DoBitmapDrawing()
        self.canvas.Refresh()

# by the way, you might not want to use Refresh(), as that might blank
and re-draw the screen, which could create some flashing you don't want.
You could probaly use a wxclientDC.DrawBitmap().

-Chris

CerCanvasEN.py (6.65 KB)

···

--
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@noaa.gov

Chris Barker wrote:

"Echeverria Rabi, Cristián" wrote:

I have a version using a memory bitmap that works on windows (It is
attached). I' am going to test this on linux later at home, but I think it
is going to work.
I put all the logical-pixel transform on a wxMemoryDC derived class.

Yes, it works on Linux, but I have a couple of suggestions for
improvements. The way you wrote it, the off-screen bitmap works for
creating a buffer for your save to file, but you don't have the other
advantages of double buffering. In yoour OnPaint method, you call
DoBitmapDrawing, so the bitmap gets re-drawn at every OnPaint event,
even though it hasn't changed.

Your OnPaint method should only blit the bitmap to the screen, and the
Drawing calls should only get called when the drawing needs updating.
also, you can blit a bitmap to a dc with the DrawBitmap method. there is
no need to set up a MemDC for that. I've made the changes to the
enclosed version, but here they are:

You may also want to take a look at the new wxBufferedDC class in 2.3.3, you can see an example of its use in the demo in wxScrolledWindow.py. It's real easy to use. All you have to do is create a bitmap for it that is the sie of your window, and recreate the bitmap when the size needs to change. Then when you want to to the bitmap without updating the screen you just do this:

  dc = wxBufferedDC(None, self.bmp)
  # draw stuff with dc

If you want to draw something and have it show up on screen do it like the following:

  dc = wxBufferedDC(wxClientDC(self), self.bmp)
  # draw stuff with dc

The bitmap will automatically be blitted to the window when the dc's reference count goes to zero and the dc is destroyed. The EVT_PAINT handler becomes only this single line:

  def OnPaint(self, evt):
      dc = wxBufferedPaintDC(self, self.bmp)

···

--
Robin Dunn
Software Craftsman
http://wxPython.org Java give you jitters? Relax with wxPython!