2011-03-01 2 views
1

Je viens de rencontrer cette situation étrange: J'ai trouvé un exemple, où OnPaint de wx.Frame est substituée, et un cercle est dessiné. Curieusement, dès que j'ajoute même un seul panneau au cadre, le cercle n'est plus dessiné - en fait, OnPaint n'est plus appelé au plus! (Btw, j'ai essayé l'exemple sur Ubuntu Lucid)wxpython: ajouter un panneau à wx.Frame désactive/est en conflit avec OnPaint de wx.Frame?

Quelqu'un peut-il m'expliquer si c'est le comportement attendu, et comment gérer correctement un wx.Frame OnPaint, si le wx.Frame a des panneaux enfants? Petit exemple de code est ci-dessous ..

Merci d'avance pour toute réponse,
Cheers!

Le code:

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

Répondre

1

OK, ce n'est pas vraiment trivial, je suppose ... Mais je l'ai trouvé le fil "wxPython - drawing without paint event - Python answers", où il est mentionné:

Une belle stratégie à partir d'un exemple dans « wxPython en action » est le suivant:

  • le cadre a Dessinez des méthodes qui dessinent un BufferedDC, qui est enchaîné à un membre bitmap,
  • dans la méthode de peinture, l'élément bitmap est dessiné à l'écran

... cependant, qui est en fait un peu trompeur - si l'on regarde un de ces exemples, comme Chapter-06/example1.py, il est à noter que l'application engendre un wx.Frame (comme dans mon exemple); mais le wx.Frame ici est simplement initialisé en instanciant un wx.Window - et il est ici où tout ce truc DC onPaint se passe.

Dans cet esprit, mon code ci-dessus peut être modifié, il fonctionne enfin à nouveau (ce cercle bleu rendu), comme ci-dessous:

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

Eh bien, espérons que cela aide quelqu'un,
Cheers!

Questions connexes