tags:

views:

337

answers:

2

Hi I am drawing a circle using wxpython for a project.Please look through the code and tell me what I am doing wrong it's not even showing any error but not drawing the circle either. I am just getting a blank window.

import wx

class SketchFrame(wx.Frame):
    def __init__(self, parent):

        wx.Frame.__init__(self, parent, -1, "Sketch Frame",size=(350,350))
        self.sketch = SketchWindow(self, -1)


class SketchWindow(wx.Window):

    def __init__ (self, parent,ID):

        wx.Window.__init__(self, parent, ID)

        self.panel =wx.Panel(self, size= (350,350))

        self.InitBuffer()


    def InitBuffer(self):

        size=self.GetClientSize()
        self.Buffer=wx.EmptyBitmap(size.width,size.height)
        dc=wx.BufferedDC(None,self.Buffer)
        dc.SetBackground(wx.Brush(self.GetBackgroundColour()))
        dc.Clear()
        self.Drawcircle(dc)
        self.reInitBuffer=False


    def Drawcircle(self,dc):
        pen=wx.Pen('blue',4)
        dc.SetPen(pen)
        dc.DrawCircle(100,100,50)

    def OnPaint(self, event):
        dc = wx.BufferedPaintDC(self, self.buffer)



if __name__=='__main__':
    app=wx.PySimpleApp()
    frame=SketchFrame(None)
    frame.Show(True)
    app.MainLoop()

Thanks

+2  A: 

Multiple problems

  1. You are not binding to EVT_PAINT e.g. self.Bind(wx.EVT_PAINT, self.OnPaint)

  2. Draw in OnPaint, but if you want to draw first and then reuse that bitmap, there is no need of BufferedPaintDC in onPaint

  3. Draw directly to buffer using wx.MemoryDC

  4. You are creating a panel in Window which will cover whatever you are drawing in window so remove that

  5. You are initializing InitBuffer at start where size may not be correct or very less you should do that in resize or call in onPaint and check if size has changed so circle is drawn correctly in centre of window on resize too

  6. Override EVT_ERASE_BACKGROUND to avoid flicker

here is the the updated code

import wx

class SketchFrame(wx.Frame):
    def __init__(self, parent):

        wx.Frame.__init__(self, parent, -1, "Sketch Frame",size=(350,350))
        self.sketch = SketchWindow(self, -1)

class SketchWindow(wx.Window):

    def __init__ (self, parent,ID):

        wx.Window.__init__(self, parent, ID)
        self.Buffer = None

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

    def InitBuffer(self):
        size=self.GetClientSize()
        # if buffer exists and size hasn't changed do nothing
        if self.Buffer is not None and self.Buffer.GetWidth() == size.width and self.Buffer.GetHeight() == size.height:
            return False

        self.Buffer=wx.EmptyBitmap(size.width,size.height)
        dc=wx.MemoryDC()
        dc.SelectObject(self.Buffer)
        dc.SetBackground(wx.Brush(self.GetBackgroundColour()))
        dc.Clear()
        self.Drawcircle(dc)
        dc.SelectObject(wx.NullBitmap)
        return True

    def Drawcircle(self,dc):
        size=self.GetClientSize()
        pen=wx.Pen('blue',4)
        dc.SetPen(pen)
        dc.DrawCircle(size.width/2,size.height/2,50)

    def OnEraseBack(self, event):
        pass # do nothing to avoid flicker

    def OnPaint(self, event):
        if self.InitBuffer():
            self.Refresh() # buffer changed paint in next event, this paint event may be old
            return

        dc = wx.PaintDC(self)
        dc.DrawBitmap(self.Buffer, 0, 0)
        self.Drawcircle(dc)

if __name__=='__main__':
    app=wx.PySimpleApp()
    frame=SketchFrame(None)
    frame.Show(True)
    app.MainLoop()
Anurag Uniyal
Thanks that helps.
Madhura
A: 

The wxPython demo is a great resource for things like this. For example, check out the demo under Miscellaneous -> DrawXXXList. This one shows how to draw a whole bunch of ellipses in a window.

Jeff
Thanks yes I will check the demo!
Madhura