2011-03-01 46 views
1

我剛剛遇到了這種奇怪的情況:我找到一個例子,其中wx.Frame的OnPaint被覆蓋,並繪製了一個圓。有趣的是,只要我在框架中添加一個單獨的面板,該圓就不再被繪製 - 事實上,OnPaint不再被稱爲,所有了! (順便說一下,我在Ubuntu Lucid上試了一下例子)wxpython:將面板添加到wx.Frame禁用/與wx.Frame的OnPaint衝突?

任何人都可以解釋我是否這是預期的行爲,以及如果wx.Frame有子面板,如何正確處理wx.Frame的OnPaint?小代碼示例如下..

在此先感謝您的任何答案,
乾杯!

代碼:

#!/usr/bin/env python 

# http://www.linuxquestions.org/questions/programming-9/wxwidgets-wxpython-drawing-problems-with-onpaint-event-703946/ 

import wx 

class MainWindow(wx.Frame): 
    def __init__(self, parent, title, size=wx.DefaultSize): 
     wx.Frame.__init__(self, parent, wx.ID_ANY, title, wx.DefaultPosition, size) 

     self.circles = list() 
     self.displaceX = 30 
     self.displaceY = 30 

     circlePos = (self.displaceX, self.displaceY) 
     self.circles.append(circlePos) 

     ## uncommenting either only first, or both of 
     ## the commands below, causes OnPaint *not* to be called anymore! 
     #~ self.panel = wx.Panel(self, wx.ID_ANY) 
     #~ self.mpanelA = wx.Panel(self.panel, -1, size=(200,50)) 

     self.Bind(wx.EVT_PAINT, self.OnPaint) 

    def OnPaint(self, e): 
     print "OnPaint called" 
     dc = wx.PaintDC(self) 
     dc.SetPen(wx.Pen(wx.BLUE)) 
     dc.SetBrush(wx.Brush(wx.BLUE)) 

     # Go through the list of circles to draw all of them 
     for circle in self.circles: 
      dc.DrawCircle(circle[0], circle[1], 10) 


def main(): 
    app = wx.App() 
    win = MainWindow(None, "Draw delayed circles", size=(620,460)) 
    win.Show() 
    app.MainLoop() 

if __name__ == "__main__": 
    main() 

回答

1

OK,這是不是真的微不足道,我想......但我發現線程 「wxPython - drawing without paint event - Python answers」,它提到:

一個不錯的從在「wxPython中在行動中」的示例策略是 以下:

  • 幀已畫出繪製成BufferedDC,其是方法 鏈接到一個位圖成員,
  • paint方法裏,位圖件繪製到屏幕

...但是,那其實是有些誤導 - 如果我們看一下其中的一個例子,如Chapter-06/example1.py,這是顯而易見的,該應用程序產生wx.Frame(如我的例子);但wx.Frame這裏只是簡單初始化一個wx.Window - 它是這裏這裏所有這些發生的東西DC onPaint

考慮到這一點,我上面的代碼可以被修改,所以它終於再次工作(即呈現藍色圓圈),如下圖所示:

#!/usr/bin/env python 

# http://www.linuxquestions.org/questions/programming-9/wxwidgets-wxpython-drawing-problems-with-onpaint-event-703946/ 

import wx 

class MainWindowWindow(wx.Window): 
    def __init__(self, parent): 
     wx.Window.__init__(self, parent) 
     self.Bind(wx.EVT_PAINT, self.OnPaint) 
     self.circles = list() 
     self.displaceX = 30 
     self.displaceY = 30 

     circlePos = (self.displaceX, self.displaceY) 
     self.circles.append(circlePos) 

     ## uncommenting either only first, or both of 
     ## the commands below, now calls onPaint 
     ## (without these panels, OnPaint called once - with them, twice) 
     self.panel = wx.Panel(self, wx.ID_ANY) 
     self.mpanelA = wx.Panel(self.panel, -1, size=(200,50)) 

    def OnPaint(self, e): 
     print "OnPaint called" 
     dc = wx.PaintDC(self) 
     dc.SetPen(wx.Pen(wx.BLUE)) 
     dc.SetBrush(wx.Brush(wx.BLUE)) 

     # Go through the list of circles to draw all of them 
     for circle in self.circles: 
      dc.DrawCircle(circle[0], circle[1], 10) 


class MainWindow(wx.Frame): 
    def __init__(self, parent, title, size=wx.DefaultSize): 
     wx.Frame.__init__(self, parent, wx.ID_ANY, title, wx.DefaultPosition, size) 
     MainWindowWindow(self) 


def main(): 
    app = wx.App() 
    win = MainWindow(None, "Draw delayed circles", size=(620,460)) 
    win.Show() 
    app.MainLoop() 

if __name__ == "__main__": 
    main() 

好了,希望這可以幫助別人,
乾杯!