wxpython 绘图到 window 导致消息对话框崩溃
wxpython drawing to window causes message dialogs to crash
我正在使用 wxpython 制作一个小绘画应用程序,如下所示:
from wx import *
class Canvas(ScrolledWindow):
def __init__(self, parent):
ScrolledWindow.__init__(self, parent, ID_ANY,(0, 0), size=DefaultSize, style=wx.SUNKEN_BORDER)
self.SetBackgroundColour('#666666')
self.sizer = BoxSizer()
self.EnableScrolling(True,True)
self.window = Window(self, size=(200,200))
self.window.SetBackgroundColour('#ffffff')
self.sizer.Add(self.window)
self.SetSizer(self.sizer)
self.SetVirtualSize((1000,1000))
self.SetScrollRate( 1, 1 )
self.Bind(EVT_PAINT, self.OnPaint)
def OnPaint(self, e):
dc = PaintDC(self.window)
dc.BeginDrawing()
dc.DrawLine( 0,0, 100, 100)
dc.EndDrawing()
class Paint(Frame):
def __init__(self, parent, title):
Fraself.__init__( self, parent, title=title, size=(500,400), style= CAPTION | RESIZE_BORDER | CLOSE_BOX)
self.CreateStatusBar(2,style= STB_DEFAULT_STYLE & ~(STB_SIZEGRIP) )
self.canvas = Canvas(self)
self.Show(True)
menu= Menu()
test = menu.Append(ID_ANY, "Create","Shows a MessageDialog")
self.Bind(EVT_MENU, self.Test, test)
menubar = MenuBar()
menubar.Append(menu,"Dialog")
self.SetMenuBar(menubar)
def Test(self, e):
dial = wx.MessageDialog(None, 'This is a test dialog.', 'Hi',
wx.OK)
dial.Show()
app = App(False)
frame = Paint(None, 'Paintbox')
app.MainLoop()
但是 MessageDialog 有一些奇怪的问题,我无法显示它,因为我在程序的其他地方使用了 PaintDC。如果我注释掉行 self.Bind(EVT_PAINT, self.OnPaint)
我可以让对话框显示,但如果我也在绘画,对话框将使程序崩溃而不打印任何错误输出。我正在使用 wxpython 3.0、python 2.7 和 Windows 8.
一些其他类型的对话框(Dialog、FileDialog)我可以正确显示。
在您的 OnPaint 中,调用:
e.Skip()
在您的测试中,调用:
dial.ShowModal()
而不是 dial.Show(),除非你真的想显示一个无模式的消息对话框,我敢打赌你不会。您还应该为 MessageDialog 设置父对象。在这种情况下它应该是 self(意思是 Paint 对象)。
您正在将事件处理程序绑定到 self
,但它正在绘制 self.window
。油漆事件对这样的事情很挑剔。您需要将处理程序绑定到 window,其中 wx.PaintDC
将用于绘图。
我正在使用 wxpython 制作一个小绘画应用程序,如下所示:
from wx import *
class Canvas(ScrolledWindow):
def __init__(self, parent):
ScrolledWindow.__init__(self, parent, ID_ANY,(0, 0), size=DefaultSize, style=wx.SUNKEN_BORDER)
self.SetBackgroundColour('#666666')
self.sizer = BoxSizer()
self.EnableScrolling(True,True)
self.window = Window(self, size=(200,200))
self.window.SetBackgroundColour('#ffffff')
self.sizer.Add(self.window)
self.SetSizer(self.sizer)
self.SetVirtualSize((1000,1000))
self.SetScrollRate( 1, 1 )
self.Bind(EVT_PAINT, self.OnPaint)
def OnPaint(self, e):
dc = PaintDC(self.window)
dc.BeginDrawing()
dc.DrawLine( 0,0, 100, 100)
dc.EndDrawing()
class Paint(Frame):
def __init__(self, parent, title):
Fraself.__init__( self, parent, title=title, size=(500,400), style= CAPTION | RESIZE_BORDER | CLOSE_BOX)
self.CreateStatusBar(2,style= STB_DEFAULT_STYLE & ~(STB_SIZEGRIP) )
self.canvas = Canvas(self)
self.Show(True)
menu= Menu()
test = menu.Append(ID_ANY, "Create","Shows a MessageDialog")
self.Bind(EVT_MENU, self.Test, test)
menubar = MenuBar()
menubar.Append(menu,"Dialog")
self.SetMenuBar(menubar)
def Test(self, e):
dial = wx.MessageDialog(None, 'This is a test dialog.', 'Hi',
wx.OK)
dial.Show()
app = App(False)
frame = Paint(None, 'Paintbox')
app.MainLoop()
但是 MessageDialog 有一些奇怪的问题,我无法显示它,因为我在程序的其他地方使用了 PaintDC。如果我注释掉行 self.Bind(EVT_PAINT, self.OnPaint)
我可以让对话框显示,但如果我也在绘画,对话框将使程序崩溃而不打印任何错误输出。我正在使用 wxpython 3.0、python 2.7 和 Windows 8.
一些其他类型的对话框(Dialog、FileDialog)我可以正确显示。
在您的 OnPaint 中,调用:
e.Skip()
在您的测试中,调用:
dial.ShowModal()
而不是 dial.Show(),除非你真的想显示一个无模式的消息对话框,我敢打赌你不会。您还应该为 MessageDialog 设置父对象。在这种情况下它应该是 self(意思是 Paint 对象)。
您正在将事件处理程序绑定到 self
,但它正在绘制 self.window
。油漆事件对这样的事情很挑剔。您需要将处理程序绑定到 window,其中 wx.PaintDC
将用于绘图。