<p>来自罗宾·邓恩本人:</p>
<blockquote>
<p>First, a <code>Refresh()</code> by default will
erase the background before sending
the paint event (although setting the
BG style or catching the erase event
would have taken care of that.) The
second and probably most visible
problem in this case is that in your
<code>on_motion</code> handler you are not
offsetting the ClientDC by the scroll
offsets, just the position in the
buffer that you are drawing the line
segment at. So when the buffer is
flushed out to the client DC it is
drawn at the physical (0,0), not the
virtual (0,0). In other words, the
flicker you are seeing is coming from
drawing the buffer at the wrong
position after every mouse drag event,
and then it immediately being drawn
again at the right position in the
<code>on_paint</code> triggered by the
<code>Refresh()</code>.</p>
<p>You should be able to fix this by
calling <code>PrepareDC</code> on the client DC
before using it, like this:</p>
<pre><code> cdc = wx.CLientDC(self)
self.PrepareDC(cdc)
dc = wx.BufferedDC(cdc, self.buffer)
</code></pre>
<p>However since you are doing a
<code>Refresh</code> or <code>RefreshRect</code> anyway,
there is no need to use a client DC
here at all, just let the flushing of
the buffer to the screen be done in
on_paint instead:</p>
<pre><code> dc = wx.BufferedDC(None, self.buffer)
</code></pre>
</blockquote>