wxpython:向wx.Frame添加面板会禁用/与wx.Frame的OnPaint冲突?

时间:2011-03-01 23:21:07

标签: wxpython panel frame draw onpaint

我刚遇到这种奇怪的情况:我找到了一个例子,其中覆盖了wx.Frame的OnPaint,并绘制了一个圆圈。有趣的是,只要我将一个面板添加到框架中,就不再绘制圆圈了 - 事实上,OnPaint不再被称为! (顺便说一下,我在Ubuntu Lucid上试过这个例子)

如果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 个答案:

答案 0 :(得分:1)

好吧,这不是真的微不足道,我猜......但我找到了线程“wxPython - drawing without paint event - Python answers”,其中提到了:

  

“wxPython in Action”中的一个例子是一个很好的策略   以下内容:

     
      
  • 框架具有绘制到BufferedDC的Draw方法,即   链接到位图成员,
  •   
  • 在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()

嗯,希望这有助于某人,
干杯!