如何在wxpython中发送PaintEvent
我正试图在wxpython中生成一个PaintEvent来触发重画窗口。然而,我似乎无法使它工作,我会出错,因为我试图在本机绘制事件之外使用PaintDC 下面是一个简单的例子:如何在wxpython中发送PaintEvent,wxpython,Wxpython,我正试图在wxpython中生成一个PaintEvent来触发重画窗口。然而,我似乎无法使它工作,我会出错,因为我试图在本机绘制事件之外使用PaintDC 下面是一个简单的例子: import wx class AppFrame(wx.Frame): def __init__(self): super(AppFrame, self).__init__(parent=None, title="Demo") self.SetClientSize((800,6
import wx
class AppFrame(wx.Frame):
def __init__(self):
super(AppFrame, self).__init__(parent=None, title="Demo")
self.SetClientSize((800,600))
self.Bind(wx.EVT_PAINT, self.paint)
self.Bind(wx.EVT_LEFT_DOWN, self.onclick)
def onclick(self, event):
wx.PostEvent(self,wx.PaintEvent())
def paint(self, event=None):
print "paint"
dc = wx.PaintDC(self)
dc.SetPen(wx.Pen(wx.BLACK, 4))
dc.DrawLine(0, 0, 50, 50)
if __name__ == "__main__":
app = wx.App(redirect=False)
appFrame = AppFrame()
appFrame.Show()
app.MainLoop()
我知道我可以在onclick处理程序中调用Refresh()来获得相同的功能(并使用CallAfter使其成为线程安全的),但我想了解为什么我不能发送PaintEvents
我使用的是MacOS10.7和WxPython3.0.1.1、Python2.7.1。我得到的错误是
File "test.py", line 17, in paint
dc = wx.PaintDC(self)
File "/usr/local/lib/wxPython-3.0.0.0/lib/python2.7/site-packages/wx-3.0-osx_cocoa/wx/_gdi.py", line 5122, in __init__
_gdi_.PaintDC_swiginit(self,_gdi_.new_PaintDC(*args, **kwargs))
wx._core.PyAssertionError: C++ assertion "window->MacGetCGContextRef() != NULL" failed at /BUILD/wxPython-src-3.0.0.0/src/osx/carbon/dcclient.cpp(195) in wxPaintDCImpl(): using wxPaintDC without being in a native paint event
调用窗口的
Refresh
方法将触发绘制事件,方法是将窗口或其子矩形标记为“已损坏”。然后,系统将尽快发送绘制事件,所有“损坏”区域将添加到事件的更新区域中。如果您希望立即发生绘制事件,而不是等待系统,那么可以调用窗口的Update
方法,但是通常正确的做法是等待系统自然发送它。您的示例在Win32位上的wxPython 2.9.5/Python 2.7.6 32位上按预期工作(单击即可处理EVT_绘制). 你在不同的平台上吗?是的,我在Mac操作系统上使用WxPython3。我编辑了我的问题。也在wxPython 3.0.0.0 msw(经典版)上测试过,这里没有问题。有趣的是,“本地”和非“本地绘画事件”的区别是什么……所以我根本不应该发送绘画事件?文档中没有提到这一点。有趣的是,将self.onclick
中的所有内容替换为self.Update()
(而不是self.Refresh())
按照建议,单击不会生成任何绘制事件。>因此我根本不应该发送绘制事件?是和否。您应该始终让系统发送绘制事件,因为需要进行一些特定于平台的整理才能使其正常工作。刷新
是您可以用来要求系统发送绘制事件的机制发送事件。更新与刷新您可以这样看:Refresh
方法要求系统将指定的矩形(或整个窗口)添加到与下一个定期计划的绘制事件一起传递的更新区域。Update
方法说,“立即发送任何挂起的绘制事件。”因此,除非已经有一个挂起的绘制事件,否则只调用Update
而不调用先前的Refresh
不会做任何事情。