how to draw in a window, device context

Hi,

I am trying to draw a circle. After reading about how to draw in a window
with device contexts in "wxPython In Action ", the following is what I came
up with. Of course it doesn't work. Why? Also, could someone explain
each line that needs to be added?

Thanks

import wx

class MyFrame(wx.Frame):
    def __init__(self, mytitle):
        wx.Frame.__init__(self, None, title=mytitle)

        panel1 = wx.Panel(self)
        dc = wx.ClientDC(panel1)
        dc.SetBackground(wx.Brush("black"))
        dc.SetPen(wx.Pen("red") )

        buffer = wx.BufferedDC(dc)
        buffer.DrawCircle(50, 50, 40)

class MyApp(wx.App):
    def __init__(self):
        wx.App.__init__(self, redirect=False)

app = MyApp()

win = MyFrame("Test")
win.Show()

app.MainLoop()

<code snipped>

This "works" as far as it goes, but since you're drawing in the
__init__ it gets erased when the window is actually show and
repainted. You need to do your drawing in an EVT_PAINT handler
instead. There's a chapter in wxPIA about this. I believe it's called
"Implementing Custom Controls", but I don't have my copy handy so I
can't check this.

···

On 6/4/07, 7stud <bbxx789_05ss@yahoo.com> wrote:

Hi,

I am trying to draw a circle. After reading about how to draw in a window
with device contexts in "wxPython In Action ", the following is what I came
up with. Of course it doesn't work. Why? Also, could someone explain
each line that needs to be added?

Thanks

Chris Mellon wrote:

Hi,

I am trying to draw a circle. After reading about how to draw in a window
with device contexts in "wxPython In Action ", the following is what I came
up with. Of course it doesn't work. Why? Also, could someone explain
each line that needs to be added?

Thanks

<code snipped>

This "works" as far as it goes, but since you're drawing in the
__init__ it gets erased when the window is actually show and
repainted. You need to do your drawing in an EVT_PAINT handler
instead. There's a chapter in wxPIA about this. I believe it's called
"Implementing Custom Controls", but I don't have my copy handy so I

The book doesn't go into it as much as I would have liked to, but you are probably thinking about section 6.1. There are a few other places as well that cover some aspects of drawing with DCs. There are also lots of examples of custom drawing in the wiki.

The key point to remember is that no drawing is persistent. As soon as the window is damaged in some way (being shown, resized, another window drags over the top of it, etc.) then it will send an EVT_PAINT event asking you to refresh the damaged portions. If you don't respond to the EVT_PAINT then nothing will be redrawn (unless the widget has it's own handler for EVT_PAINT of course.)

···

On 6/4/07, 7stud <bbxx789_05ss@yahoo.com> wrote:

--
Robin Dunn
Software Craftsman
http://wxPython.org Java give you jitters? Relax with wxPython!

Chris Mellon <arkanes <at> gmail.com> writes:

This "works" as far as it goes, but since you're drawing in the
__init__ it gets erased when the window is actually show and
repainted. You need to do your drawing in an EVT_PAINT handler
instead. There's a chapter in wxPIA about this. I believe it's called
"Implementing Custom Controls", but I don't have my copy handy so I
can't check this.

Thanks for the explanation. The cobwebs are clearing a bit from the
memories of some C++ GUI programming I once did. Now I seem to
recall that a window is painted when:

1) it's initially displayed

2) it's covered up and then uncovered.

And in order to draw in a window, you have to intercept a paint
message that is issued in response to those events, and then draw
your window the way you want it.

Unfortunately, "wxPython in Action" fails to mention the fact that
you need to listen for wx.EVT_PAINT and then draw the
window inside the event handler. There is no mention of that fact in
section 6.1 "Drawing to the Screen" nor in section 12.2.2 "How do
I draw to a device context?", and the examples are so long and
convoluted, it's not possible fora beginner to discern that requirement
from the examples.

I had problems trying to understand drawing in wxPython, and could
never seem to get it to work properly. Then I discovered Dabo
(http://dabodev.com).

You say you want to draw a circle. All it takes in Dabo is:

circ = object.drawCircle(x, y, radius)

You can also specify stuff like PenColor, PenWidth, FillColor, etc.
The circle is drawn to your settings, and redraws itself as needed
without any code on your part. And the object reference it returns is
'live' - you can change any of its properties, and the drawn circle
changes accordingly. So if you want to change it to be filled with
blue, you just write:

circ.FillColor = "blue"

And it just works!

···

On 6/4/07, 7stud <bbxx789_05ss@yahoo.com> wrote:

Thanks for the explanation. The cobwebs are clearing a bit from the
memories of some C++ GUI programming I once did. Now I seem to
recall that a window is painted when:

1) it's initially displayed

2) it's covered up and then uncovered.

And in order to draw in a window, you have to intercept a paint
message that is issued in response to those events, and then draw
your window the way you want it.

Unfortunately, "wxPython in Action" fails to mention the fact that
you need to listen for wx.EVT_PAINT and then draw the
window inside the event handler. There is no mention of that fact in
section 6.1 "Drawing to the Screen" nor in section 12.2.2 "How do
I draw to a device context?", and the examples are so long and
convoluted, it's not possible fora beginner to discern that requirement
from the examples.

--

# p.d.