wxpython: добавление панели в wx.Frame отключает / конфликтует с OnPaint wx.Frame? - PullRequest
1 голос
/ 02 марта 2011

Я только что столкнулся с этой странной ситуацией: я нашел пример, где OnPaint wx.Frame переопределяется, и рисуется круг.Как ни странно, как только я добавляю хотя бы одну панель в рамку, круг больше не рисуется - фактически 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()

1 Ответ

1 голос
/ 02 марта 2011

ОК, это не совсем тривиально, я думаю ... Но я нашел поток " wxPython - рисование без события рисования - Python отвечает ", где упоминается:

Одна из хороших стратегий из примера в "wxPython in Action" заключается в следующем:

  • фрейм имеет методы Draw, которые рисуют в BufferedDC, который связан с элементом растрового изображения,
  • внутри метода рисования, элемент растрового изображения рисуется на экране

... однако, это на самом деле немного вводит в заблуждение - если мы посмотрим на один из этих примеров, такой как 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()

Что ж, надеюсь, это кому-то поможет,
Ура!

...