好的,我发现了问题,但稍后我会尝试发布更多详细信息。
基本上,这段代码的目标是移动一个面板,然后更新父面板。 SetPosition 调用Move,它通过wxWidget 代码调用DoMoveWindow,所有这些都会导致位置变化和重绘调用(还不确定是什么调用重绘)。伟大的。然而,重绘只标记了某个“区域”,因为它试图提高效率。这就是为什么可以通过让面板越过“幻影”区域来解决某些问题的原因。您要做的是在 SetPosition 之后调用 GetParent().Refresh(),它将发送一个没有任何排除区域的“完整”绘制。
另外需要注意的是,这个“损坏”或“剪断”区域有两个术语。一个是“损坏”,但还有另一个是“脏”。 wx PaintDC信息中使用了伤害
在 EVT_PAINT 处理程序中使用 wx.PaintDC 很重要,因为它
自动将剪辑区域设置为损坏区域
窗户。不会出现在此区域之外绘制的尝试。
相信文档会让您迷失方向。然而,在其中一个 wxPython DoubleBuffer 中,术语如何变化(但它与“损坏”相同)
现在是 OnPaint() 方法。每当发生疼痛事件时都会调用它
由系统发送:即每当窗口的一部分变得脏。
知道这一点,如果你 Google wx Window 脏了,你会得到以下信息
标记指定的矩形(或整个窗口)为“脏”所以它
将被重新粉刷。导致生成并发送 EVT_PAINT 事件
到窗口。
在以下三个打印周期中,在 SetPosition 调用后触发了 EVT_PAINT(这是没有 GetParent().Refresh() 调用)
# first EVT_PAINT
Drawing
Panel Size (1440, 851)
Clipping Rect (0, 0, 1440, 851)
Client Update Rect (x=0, y=6, w=500, h=501) # the only place getting update is
# directly below the panel
# (that is (500, 500) )
# second
Drawing
Panel Size (1440, 851)
Clipping Rect (0, 0, 1440, 851)
Client Update Rect (x=0, y=6, w=910, h=845) # however this time the update area is
# bigger, this is also right before
# the move
# i believe what it is doing is
# drawing from (0,6) to (910, 851)
# why? because the panel is moving to
# (410, 390) and the bottom right
# corner of the panel (after moved)
# is (410+500, 390+461) = (910, 851)
# or about where the edge of the panel
# will be
# third
Drawing
Panel Size (1440, 851)
Clipping Rect (0, 0, 1440, 851)
Client Update Rect (x=410, y=390, w=500, h=461)
这是可以玩的更新代码,希望这对其他人有帮助。
import wx
instructions = """
How to use.
1) Hover your mouse over the pink panel.
2) Click down (left click)
3) While holding down drag mouse around
4) Release mouse button to stop.
"""
class AppPanel(wx.Panel):
def __init__(self, parent, id):
wx.Panel.__init__(self, parent, id)
self.sizer = wx.BoxSizer(wx.VERTICAL)
self.settings_sizer = wx.BoxSizer(wx.HORIZONTAL)
p = MovablePanel(self, -1)
self.c = wx.CheckBox(self, -1, label = "Ghosting On?")
self.p = p
self.i = 0
self.settings_sizer.Add(self.c)
self.sizer.Add(self.settings_sizer)
self.sizer.Add(self.p)
self.SetSizer(self.sizer)
self.Layout()
self.Bind(wx.EVT_CHECKBOX, self.OnCheck, self.c)
self.Bind(wx.EVT_PAINT, self.OnPaint, self)
self.Bind(wx.EVT_ERASE_BACKGROUND, self.OnErase, self)
def OnCheck(self, event):
print "CHECK\n\n\n\n\n"
v = self.c.GetValue()
self.p.r = v
print v
def OnErase(self, event):
pass
def OnPaint(self, event):
print "Drawing"
dc = wx.PaintDC(self)
print "Panel Rect, ", self.p.GetPosition(),
print self.p.GetSize()
print "Clipping Rect", dc.GetClippingBox()
print "Client Update Rect", self.GetUpdateClientRect()
print "----------------------------"
self.i = self.i+10
c = self.i % 255
c = (0, 0, c)
dc.SetPen(wx.Pen(c))
dc.SetBrush(wx.Brush(c))
dc.DrawRectangle(0, 0, 10000,10000)
self.SetBackgroundColour(c)
dc.SetPen(wx.Pen("WHITE"))
dc.SetBrush(wx.Brush("WHITE"))
dc.DrawRectangle(0, 0, self.GetSize()[0], self.c.GetSize()[1])
class MovablePanel(wx.Panel):
def __init__(self, parent, id):
wx.Panel.__init__(self, parent, id)
self.SetMinSize((300,300))
self.SetSize((300,300))
txt = wx.StaticText(self, -1, label = "CLICK AND DRAG ME!")
inst = wx.StaticText(self, -1, label = instructions)
font = wx.Font(18, wx.SWISS, wx.NORMAL, wx.BOLD)
txt.SetFont(font)
inst.SetFont(font)
sizer = wx.BoxSizer(wx.VERTICAL)
sizer.Add(txt, flag = wx.ALIGN_CENTRE_VERTICAL | wx.ALIGN_CENTRE_HORIZONTAL)
sizer.Add(inst, flag = wx.ALIGN_CENTRE_VERTICAL | wx.ALIGN_CENTRE_HORIZONTAL)
self.SetSizer(sizer)
self.SetBackgroundColour("PINK")
self.LEFT_DOWN = False
self.r = False
self.Bind(wx.EVT_MOTION, self.OnMove, self)
self.Bind(wx.EVT_LEFT_DOWN,
self.OnClickDown,
self)
self.Bind(wx.EVT_LEFT_UP,
self.OnClickUp,
self)
def OnClickUp(self, event):
self.LEFT_DOWN = False
self.Refresh()
def OnClickDown(self, event):
self.LEFT_DOWN = True
self.Refresh()
def OnMove(self, event):
if self.LEFT_DOWN:
p = self.GetTopLevelParent().ScreenToClient(wx.GetMousePosition())
self.SetPosition(p)
if not self.r:
self.GetParent().Refresh()
if __name__ == "__main__":
app = wx.App(False)
f = wx.Frame(None, -1, size = (700, 700))
p = AppPanel(f, -1)
f.Show()
app.MainLoop()