1

刚遇到这种奇怪的情况:我找了一个例子,覆盖了wx.Frame的OnPaint,画了一个圆。有趣的是,只要我在框架中添加了一个面板,就不再绘制圆圈了——事实上,根本不再调用 OnPaint!(顺便说一句,我在 Ubuntu Lucid 上尝试了这个例子)

如果这是预期的行为,谁能解释我,以及如何正确处理 wx.Frame OnPaint,如果 wx.Frame 有子面板?小代码示例如下..

提前感谢您的任何答案,
干杯!

编码:

#!/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()
4

1 回答 1

1

好的,我猜这不是微不足道的......但我发现了线程“ wxPython - 没有绘画事件的绘图 - Python 答案”,其中提到了它:

“wxPython in Action”中的一个例子中的一个很好的策略如下:

  • 框架具有绘制到 BufferedDC 中的 Draw 方法,该 BufferedDC 链接到位图成员,
  • 在paint方法中,位图成员被绘制到屏幕上

...但是,这实际上有点误导-如果我们查看其中一个示例,例如Chapter-06/example1.py,很明显该应用程序产生了一个wx.Frame(如我的示例中所示);但是wx.Frame这里只是通过实例化 a wx.Window- 来简单地初始化,而这里就是所有这些 DConPaint事情发生的地方。

考虑到这一点,我上面的代码可以修改,所以它终于可以再次工作(即呈现蓝色圆圈),如下所示:

#!/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()

好吧,希望这对某人有所帮助,
干杯!

于 2011-03-02T11:32:37.610 回答