Why doesn't this draw on my wxPython DC?

Lexy Zhitenev zhitenev at cs.vsu.ru
Fri Feb 28 08:50:27 EST 2003


"Brian Elmegaard" <brian at rk-speed-rugby.dk> wrote in message:
news:uadgg3igj.fsf at mail.afm.dtu.dk...
> ================================================================
> from wxPython.wx import *
>
> class MyCanvas(wxScrolledWindow):
>     def __init__(self, parent, id = -1, size = wxDefaultSize):
>         wxScrolledWindow.__init__(self, parent, id, wxPoint(0, 0), size,
wxSUNKEN_BORDER)
>
>         self.buffer=wxEmptyBitmap(100,100)
>         dc=wxBufferedDC(None, self.buffer)
>         dc.SetBackground(wxBrush(self.GetBackgroundColour()))
>         dc.Clear()
>         dc.BeginDrawing()
>         dc.DrawRectangle(10,10,100,100)
>         dc.EndDrawing()
>
>         EVT_PAINT(self,self.OnPaint)
>
>     def OnPaint(self,event):
>         dc = wxBufferedPaintDC(self,self.buffer)
>
> app=wxPySimpleApp()
> frame=wxFrame(None,-1,"Test")
> win = MyCanvas(frame)
> frame.Show(true)
> app.MainLoop()
> ========================================================
> and draws a rectangle on the window. I could go on living happily, but
> I would like to know why do I need a DC in both __init__ and OnPaint.

You need DC to paint. You can Paint only on a Device Context.
You create a buffered DC and paint on it. It is not a screen device context,
but a memory one.
When you paint inside OnPaint event handler, you just copy the contents of
your memory dc to your paint dc.
Inside OnPaint handler, only PaintDCs are available. The specifics is such.

> Why do I need to have the EVT_PAINT when the docs say:
> "To draw on a window from outside OnPaint, construct a wxClientDC
> object."?
Certainly.

> Removing the event and changing the dc line in __init__ to use a
> wxClientDC does not draw anything.
Yes, it does. You just don't see it, because here comes OnPaint event and
clears what you have painted on a ClientDC.

>
> What are the arguments I feed to the DC's. Buffered DC is not
> mentioned anywhere in the doc AFAICS.
I don't have the docs here. Maybe later I'll look for it.
Generally, you need no arguments if you are _constructing_ or _getting_ a
DC, and you need one or more if you are _copying_ a DC.

If you construct a MemoryDC or BufferedDC, you don't need any arguments.
If you want to paint on a standard DC, such as screen, client window or
printer, you are getting a DC
Copying, I think, doesn't need to be explained.

>
> Another question is what is the difference between the different
> wxDC's (Paint, Client, Buffered, BufferedPaint,...)?
>
Roughly, use
PaintDC - to paint inside OnPaint event
ClientDC - to paint on the client area of the window
Buffered... - to paint everything in memory and then just copy the image to
a DC. used for speeding up.

Read the documentation for details, or write a letter to me. I'll answer you
as soon as I get to the documentation.

> Could I do it without the class MyCanvas and completely procedural? I
> believe not as I can't figure out what arguments to give to the
> EVT_PAINT and the OnPaint if not self from a class. Does the script
> itself have a 'self'?

No, you can't. Your classes are derived from wxWindow. This class knows how
to paint itself, and it already has a DC. You get it and use. The object of
this class draws itself in a window. wxWindow class is responsible for
creating it.
self is an attribute of class, not of a script. Script is not a class also.
However, if you dare, you can globally get a whole screen device context and
paint directly on the screen, not being tied to a window. You can dare to
get a device context, associated with another window, but I guess you
shouldn't! Remember, your application won't work, you won't get any DC if
you has not constructed a wxApp instance already.

> Now when I have got it running I would like to be able to click on
> items on the window, open an entry and write the input on this on the
> DC.
> I make a left down event reacting with:
>     def OnLeftDown(self,event):
>         dlg = wxTextEntryDialog(frame,"Write here","Entry","")
>         dlg.ShowModal()
>
> I then would like to draw the output from dlg.GetValue() on the DC,
> but a new wxBufferedDC written exactly as in __init__ doesn't draw. Why?
Right now, I can't figure it out.

>
> A lot of questions which I hope someone will give me some information
> on.
>

Contact me.

Lexy zhitenev at cs.vsu.ru







More information about the Python-list mailing list