Hi:
I have been tinkering with the drawing program (listing 6.1) in the book (code quoted below with my comments, modifications, and diagnostics), and have grasped about 95% of it.
Now I'm experimenting with one or both of two critical lines which affect repainting the Window. I've also made the Window background green to distinguish it from the bitmap buffer background (white).
The lines are:
1. In the SketchWindow class OnIdle method:
self.Refresh(eraseBackground=False)
2. In the OnPaint method:
dc = wx.BufferedPaintDC(self, self.buffer)
I will explain the results of my experiments. Two permutaions I understand and a third I don't. The third case is the origin of my question. Here are the permutations:
Experiment: OnPaint Refresh()
1. not commented commented
2. commented commented
3. commented not commented
Explanation of experiment 1:
When the window appears, it is green because the bitmap buffer has not yet been blitted. That therefore appears to be the main purpose of the Refresh() call, to get the initial buffer displayed on the Window. As soon as OnMotion gets called by mouse dragging, then the first dropping out of scope of the device context in OnMotion causes the buffer to be displayed. Thus the background turns white.
This experiment revealed some interesting things. When the Refresh is not explicitly called, then I still get Paint events when resizing the
Window larger, but not smaller. So there is another mechanism which
creates Paint events besides explicit Refresh calls. Window manager activity seems able to cause Paint events to occur.
Explanation of experiment 2:
In this case Paint events are not processed by the line shown above, though we get the printed diagnostic telling us when Paint events occurred. We find in this situation that everything works as in exp. 1 until a resize is attempted or another window overlays this one.
Again we start with a green background, then the first drawing activity blits the buffer which has the white background. Resizing larger causes green Window background to appear where the buffer isn't. The buffer is still being resized in this case by InitBuffer, but not getting blitted to the Window, until another drawing event.
Experiment 3:
In this case, once we draw something and get the buffer sent to the Window, then any resize whether larger or smaller causes the entire Window to turn green. Yet, another window overlaying only causes the affected region to turn green.
Why does the entire buffer image get blown away in this case and not in experiment 2?
Thanks for input!
Listing 6.1 from "wxPython in Action" with modifications, and set up for experiment 1:
···
-------------------------------------------------------------------
import wx
class SketchWindow(wx.Window):
def __init__(self, parent, ID):
wx.Window.__init__(self, parent, ID)
self.SetBackgroundColour("Green")
self.color = "Red"
self.thickness = 1
self.pen = wx.Pen(self.color, self.thickness, wx.SOLID)
self.lines = []
self.curLine = []
self.pos = (0, 0)
self.InitBuffer()
self.Bind(wx.EVT_LEFT_DOWN, self.OnLeftDown)
self.Bind(wx.EVT_LEFT_UP, self.OnLeftUp)
self.Bind(wx.EVT_MOTION, self.OnMotion)
self.Bind(wx.EVT_SIZE, self.OnSize)
self.Bind(wx.EVT_IDLE, self.OnIdle)
self.Bind(wx.EVT_PAINT, self.OnPaint)
def InitBuffer(self):
size = self.GetClientSize()
print "InitBuffer: size=", size
self.buffer = wx.EmptyBitmap(size.width, size.height)
dc = wx.BufferedDC(None, self.buffer)
dc.SetBackground(wx.Brush("White"))
dc.Clear()
self.DrawLines(dc)
self.reInitBuffer = False
def OnLeftDown(self, event):
self.curLine = []
self.pos = event.GetPositionTuple()
print "OnLeftDown: pos=", self.pos
self.CaptureMouse()
def OnLeftUp(self, event):
if self.HasCapture():
print "OnLeftUp: with HasCapture"
self.lines.append((self.color,
self.thickness,
self.curLine))
self.curLine = []
self.ReleaseMouse()
def OnMotion(self, event):
if event.Dragging() and event.LeftIsDown():
dc = wx.BufferedDC(wx.ClientDC(self), self.buffer)
self.drawMotion(dc, event)
event.Skip()
def drawMotion(self, dc, event):
dc.SetPen(self.pen)
newPos = event.GetPositionTuple()
coords = self.pos + newPos
print "drawMotion: coords=", coords
self.curLine.append(coords)
dc.DrawLine(*coords)
self.pos = newPos
def OnSize(self, event):
print "OnSize"
self.reInitBuffer = True
def OnIdle(self, event):
if self.reInitBuffer:
print "OnIdle: with reInitBuffer"
self.InitBuffer()
# self.Refresh(False)
def OnPaint(self, event):
print "OnPaint"
dc = wx.BufferedPaintDC(self, self.buffer)
def DrawLines(self, dc):
for colour, thickness, line in self.lines:
pen = wx.Pen(colour, thickness, wx.SOLID)
dc.SetPen(pen)
for coords in line:
dc.DrawLine(*coords)
class SketchFrame(wx.Frame):
def __init__(self, parent):
wx.Frame.__init__(self, parent, -1, "Sketch Frame",
size=(800,600))
self.sketch = SketchWindow(self, -1)
if __name__ == '__main__':
app = wx.PySimpleApp()
frame = SketchFrame(None)
frame.Show(True)
app.MainLoop()
-------------------------------------------------------------------
--
_____________________
Christopher R. Carlen
crobc@bogus-remove-me.sbcglobal.net
SuSE 9.1 Linux 2.6.5