refresh problems

Hello,

Leaning on "wxPython in Action", I now have code to draw a graph on a buffer.
For some reason though, while it doesn't do this on Linux, on Windows, the
buffer isn't clearing itself on each paint event like I'd like, so remnants of
previous drawings are present after a resize.

    def OnPaint(self, event):
        """Paint the window. We call InitBuffer here each time to detect the
        current size of the drawing area."""
        self.InitBuffer()
        dc = wx.BufferedPaintDC(self, self.buffer)

    def InitBuffer(self):
        """Initialize the buffer, and draw the lines on it."""
        size = self.GetClientSize()
        self.buffer = wx.EmptyBitmap(size.width, size.height)
        dc = wx.BufferedDC(None, self.buffer)
        dc.SetBackground(wx.Brush(self.GetBackgroundColour()))
        dc.SetFont(self.defaultFont)
        dc.Clear()

        self.leftMargin = int(self.leftMarginFactor*size.width)
        self.bottomMargin = int(size.height -
self.bottomMarginFactor*size.height)
        self.rightMargin = int(size.width - self.rightMarginFactor*size.width)
        self.topMargin = int(self.topMarginFactor*size.height)

        self.DrawLabels(dc)
        self.DrawAxes(dc)
        self.DrawLines(dc)
        self.reInitBuffer = False

I suspect that the drawing itself is unimportant, I can only assume that I'm
missing a critical wiping of the previous graphics context. Some help
appreciated.

Thanks,
Mike

···

--
Michael P. Soulier <msoulier@digitaltorque.ca>
"Any intelligent fool can make things bigger and more complex... It takes a
touch of genius - and a lot of courage to move in the opposite direction."
--Albert Einstein

Michael P. Soulier wrote:

Leaning on "wxPython in Action", I now have code to draw a graph on a buffer.
For some reason though, while it doesn't do this on Linux, on Windows, the
buffer isn't clearing itself on each paint event like I'd like, so remnants of
previous drawings are present after a resize.

This is odd. The call to dc.Clear() should set the whole buffer to the background color. However, while I'm not sure what you issue is, I have a few comments:

First: put some example code in a small working app that does just what you need to show the problem, and no more. You may find the problem yourself this way, and if you don't, we'll have something we can run ourselves, to test and tweak.

    def OnPaint(self, event):
        """Paint the window. We call InitBuffer here each time to detect the
        current size of the drawing area."""
        self.InitBuffer()
        dc = wx.BufferedPaintDC(self, self.buffer)

You don't want to re-init the buffer in every Paint event. This kind of defeats the purpose of double buffering. The buffer doesn't need to change unless the Window size changes, so you want to call InitBuffer in a SIZE event instead. OnPaint should ONLY dump the buffer to the screen.

See the Double buffered pages in the Wiki for more discussion and examples.

    def InitBuffer(self):
        """Initialize the buffer, and draw the lines on it."""
        size = self.GetClientSize()
        self.buffer = wx.EmptyBitmap(size.width, size.height)

This is pretty much all you should have in the InitBuffer Code. The actual drawing should be in a separate method.

Also, why start from scratch? I'm not sure what you mean by "graph", but is supect that wxPyPlot, or matplotlib, or floatcanvas or wxOGL would likely suit your needs.

-Chris

Michael P. Soulier wrote:

Hello,

Leaning on "wxPython in Action", I now have code to draw a graph on a buffer.
For some reason though, while it doesn't do this on Linux, on Windows, the
buffer isn't clearing itself on each paint event like I'd like, so remnants of
previous drawings are present after a resize.

By default the paint event will only update the newly exposed region of the window. The rest is clipped out of the update region. If you want to always repaint the whole window then use the wx.FULL_REPAINT_ON_RESIZE style.

BTW, if you're going to be redrawing the whole window (by recreating the whole buffer) on every repaint then there is no advantage to using the buffer.

···

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

By default the paint event will only update the newly exposed region of
the window. The rest is clipped out of the update region. If you want
to always repaint the whole window then use the
wx.FULL_REPAINT_ON_RESIZE style.

Ok, thanks.

BTW, if you're going to be redrawing the whole window (by recreating the
whole buffer) on every repaint then there is no advantage to using the
buffer.

Yeah, I figured, but I was trying to get _something_ working before
optimizing.

Mike

···

On 25/07/06 Robin Dunn said:

--
Michael P. Soulier <msoulier@digitaltorque.ca>
"Any intelligent fool can make things bigger and more complex... It
takes a touch of genius - and a lot of courage to move in the opposite
direction." --Albert Einstein

First: put some example code in a small working app that does just what
you need to show the problem, and no more. You may find the problem
yourself this way, and if you don't, we'll have something we can run
ourselves, to test and tweak.

It's pretty small already actually, but yes, runnable would help.

You don't want to re-init the buffer in every Paint event. This kind of
defeats the purpose of double buffering. The buffer doesn't need to
change unless the Window size changes, so you want to call InitBuffer in
a SIZE event instead. OnPaint should ONLY dump the buffer to the screen.

Just trying to get something working first.

This is pretty much all you should have in the InitBuffer Code. The
actual drawing should be in a separate method.

I suppose. I took most of it from said book, and added my own.

Also, why start from scratch? I'm not sure what you mean by "graph", but
is supect that wxPyPlot, or matplotlib, or floatcanvas or wxOGL would
likely suit your needs.

Already fought with the limitations of both wx.lib.plot and matplotlib, and
I'm sick of trying to understand someone else's poorly documented API. I'm
fed-up frankly, so I'm doing it myself. My needs are simple line graphs, but I
want flexibility of labels or types of axes, and I'm tired of looking for,
"how do I do this in API X"?

Mike

···

On 25/07/06 Christopher Barker said:

--
Michael P. Soulier <msoulier@digitaltorque.ca>
"Any intelligent fool can make things bigger and more complex... It
takes a touch of genius - and a lot of courage to move in the opposite
direction." --Albert Einstein

Michael P. Soulier wrote:

Also, why start from scratch?

Already fought with the limitations of both wx.lib.plot and matplotlib, and
I'm sick of trying to understand someone else's poorly documented API. I'm
fed-up frankly, so I'm doing it myself.

Well, always the quandary: Do I spend time learning a new lib, or just writing the code yourself?

My needs are simple line graphs, but I
want flexibility of labels or types of axes, and I'm tired of looking for,
"how do I do this in API X"?

Well, as you're seen, you'll spend a fair bit of time just getting the buffering and all right if you do it yourself.

Anyway, wx.lib.plot, is very simple, and thus you likely can't make ti do what you want. However, it's also simple enough that you could figure out the code and tweak it do the things you want, probably faster that writing it all from scratch.

FloatCanvas could be used too. I have a small sample of a line plot, but not with me at the moment. I'll send it to you if you ask.

Of course, the is the educational value of writing from scratch.

You could at least start with the DoubleBufferedWindow from the Wiki though.

-Chris

···

On 25/07/06 Christopher Barker said:

--
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