下面,我在一个框架内有一个面板。为什么我无法抽到面板?我只是得到一个纯白色的屏幕。如果我摆脱面板并直接绘制到框架......它的工作原理。任何帮助将不胜感激。
import wx
class MyFrame(wx.Frame):
def __init__(self):
wx.Frame.__init__(self,None,-1,'window',(200,200),(600,600))
self.Center()
self.panel=wx.Panel(self)
self.panel.SetBackgroundColour('white')
self.firstpoint=wx.Point(300,300)
self.secondpoint=wx.Point(400,400)
self.Bind(wx.EVT_PAINT,self.onPaint)
def onPaint(self,event):
dc=wx.PaintDC(self.panel)
dc.DrawLine(self.firstpoint.x,self.firstpoint.y,
self.secondpoint.x,self.secondpoint.y)
答案 0 :(得分:7)
尝试将事件绑定到面板,而不是整个框架:
self.panel.Bind(wx.EVT_PAINT, self.onPaint)
您的版本对我来说是一种工作(windows),但它不断重绘面板,因此它会占用整个处理器。
来自文档: 请注意,在paint事件处理程序中,即使您不使用它,应用程序也必须始终创建一个wxPaintDC对象。否则,在MS Windows下,刷新此窗口和其他窗口将出错。
在这里,您收到了整个画面的绘画事件,但是使用了DC作为面板。
编辑:http://wiki.wxpython.org/self.Bind%20vs.%20self.button.Bind很好地解释了为什么这不起作用:
self.Bind(wx.EVT_PAINT, self.onPaint, self.panel)
在这种情况下,永远不会调用onPaint处理程序。
答案 1 :(得分:1)
我正在寻找一个完整的自定义wx Python控件的完整工作示例,它继承wx.Panel
并自行进行自定义绘图,而我找不到任何东西。感谢这个(以及其他)问题,我终于设法找到了一个最小的工作示例 - 我将在这里发布,因为它确实显示了“绘制到框架内的面板”;除了OP之外,Frame在Panel上绘制图形 - 这里面板自行绘制(坐在框架中)。
代码生成如下内容:
...当您调整窗口大小时,基本上会重绘红色矩形。
注意代码注释,特别是OnSize中需要Refresh()以避免损坏的渲染/闪烁。
MWE代码:
import wx
# tested on wxPython 2.8.11.0, Python 2.7.1+, Ubuntu 11.04
# http://stackoverflow.com/questions/2053268/side-effects-of-handling-evt-paint-event-in-wxpython
# http://stackoverflow.com/questions/25756896/drawing-to-panel-inside-of-frame-in-wxpython
# http://www.infinity77.net/pycon/tutorial/pyar/wxpython.html
# also, see: wx-2.8-gtk2-unicode/wx/lib/agw/buttonpanel.py
class MyPanel(wx.Panel): #(wx.PyPanel): #PyPanel also works
def __init__(self, parent, id=wx.ID_ANY, pos=wx.DefaultPosition, size=wx.DefaultSize, style=0, name="MyPanel"):
super(MyPanel, self).__init__(parent, id, pos, size, style, name)
self.Bind(wx.EVT_SIZE, self.OnSize)
self.Bind(wx.EVT_PAINT, self.OnPaint)
def OnSize(self, event):
print("OnSize" +str(event))
#self.SetClientRect(event.GetRect()) # no need
self.Refresh() # MUST have this, else the rectangle gets rendered corruptly when resizing the window!
event.Skip() # seems to reduce the ammount of OnSize and OnPaint events generated when resizing the window
def OnPaint(self, event):
#~ dc = wx.BufferedPaintDC(self) # works, somewhat
dc = wx.PaintDC(self) # works
print(dc)
rect = self.GetClientRect()
# "Set a red brush to draw a rectangle"
dc.SetBrush(wx.RED_BRUSH)
dc.DrawRectangle(10, 10, rect[2]-20, 50)
#self.Refresh() # recurses here!
class MyFrame(wx.Frame):
def __init__(self, parent):
wx.Frame.__init__(self, parent, -1, "Custom Panel Demo")
self.SetSize((300, 200))
self.panel = MyPanel(self) #wx.Panel(self)
self.panel.SetBackgroundColour(wx.Colour(10,10,10))
self.panel.SetForegroundColour(wx.Colour(50,50,50))
sizer_1 = wx.BoxSizer(wx.HORIZONTAL)
sizer_1.Add(self.panel, 1, wx.EXPAND | wx.ALL, 0)
self.SetSizer(sizer_1)
self.Layout()
app = wx.App(0)
frame = MyFrame(None)
app.SetTopWindow(frame)
frame.Show()
app.MainLoop()