Flicker when updating a bitmap

I have a window, derived from wxFrame, that is used to display graphics coming in over the net. self.image is a bitmap. The following OnPaint works pretty well, but there is a good deal of flicker every few frames. Is there a more efficient method to draw to the window that will do a better job of elimating the flicker? Or is the flicker there just because I have a pretty old, slow computer, K6-2 450?

def OnPaint(self, event):
  if not self.image:
    return
  tempDC = wxMemoryDC()
  mainDC = wxPaintDC(self)
  mainDC.BeginDrawing()
  tempDC.SelectObject(self.image)
  size = wxSize(self.image.GetWidth(), self.image.GetHeight())
  if size != self.GetClientSize():
    self.SetClientSize(size)
  mainDC.Blit(0, 0, self.image.GetWidth(), self.image.GetHeight(), tempDC, 0, 0)
  mainDC.EndDrawing()

Scott wrote:

I have a window, derived from wxFrame, that is used to display graphics coming in over the net. self.image is a bitmap. The following OnPaint works pretty well, but there is a good deal of flicker every few frames. Is there a more efficient method to draw to the window that will do a better job of elimating the flicker?

maybe.

Or is the flicker there just because I have a pretty old, slow computer, K6-2 450?

No.

I suspect that what is happening is that the window is being cleared,
and then the new image drawn, rather than the new image being drawn on
top of the old one. a wxPaintDC will sometimes do that.

From your description, you shouldn't be updating the image in the

OnPaint method. That method should only be called when the system is
calling for the window to be updated. If the window is just sitting on
top of everything and you want to change it's contents, you want to use
a wxClientDC in some kind of Update() method, callled when there is a
new image. Something like this (untested):
2
def Update(self,event):
    if not self.image:
        return
    mainDC = wxClientDC(self)
    mainDC.BeginDrawing()
    mainDC.DrawBitmap(self.image, 0, 0)
    mainDC.EndDrawing()

This should get called when there is a new image available, probably by
generating an event from the code downloading your stuff from the net.
Note that I am using DC.DrawBitmap(), it's a little easier to use than
DC.Blit(), but I'm not sure it's any faster. You'll still need an
OnPaint method similar to yours for when the system tells your app that
the screen needs to be updated.

Let us know if this works better,

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

Well Chris, a week later, I've finally found the time to try this. And
thank you. It has completely eliminated flicker. Completely! I don't
really understand why, I guess I need to study device contexts a bit.
Thanks for the help. Sorry it took me so long.

···

On Tue, 08 Jul 2003 09:31:27 -0700 Chris Barker <Chris.Barker@noaa.gov> wrote:

Scott wrote:

> I have a window, derived from wxFrame, that is used to display
> graphics coming in over the net. self.image is a bitmap. The
> following OnPaint works pretty well, but there is a good deal of
> flicker every few frames. Is there a more efficient method to draw
> to the window that will do a better job of elimating the flicker?

maybe.

> Or is the flicker there just because I have a pretty old, slow
> computer, K6-2 450?

No.

I suspect that what is happening is that the window is being cleared,
and then the new image drawn, rather than the new image being drawn on
top of the old one. a wxPaintDC will sometimes do that.

From your description, you shouldn't be updating the image in the
OnPaint method. That method should only be called when the system is
calling for the window to be updated. If the window is just sitting on
top of everything and you want to change it's contents, you want to
use a wxClientDC in some kind of Update() method, callled when there
is a new image. Something like this (untested):
2
def Update(self,event):
    if not self.image:
        return
    mainDC = wxClientDC(self)
    mainDC.BeginDrawing()
    mainDC.DrawBitmap(self.image, 0, 0)
    mainDC.EndDrawing()

This should get called when there is a new image available, probably
by generating an event from the code downloading your stuff from the
net. Note that I am using DC.DrawBitmap(), it's a little easier to use
than DC.Blit(), but I'm not sure it's any faster. You'll still need an
OnPaint method similar to yours for when the system tells your app
that the screen needs to be updated.

Let us know if this works better,