Problems with DCs

I'm trying to do some simple drawing on a panel, and nothing is showing up. Here's the code:

self.dc = wx.ClientDC(self)
self.dc.SetPen(wx.Pen("black", 1, wx.SOLID))
self.dc.SetBrush(wx.RED_BRUSH)
self.dc.DrawRectangle( (50,50), (25,30) )

  The panel appears normally, but no rectangle is drawn on it.

  wxPython v.2.5.1.5, RH Linux 8.

      ___/
     /
    __/
   /
  ____/
  Ed Leafe
  http://leafe.com/
  http://opentech.leafe.com

Oh, I should mention that I've tried various combinations of Pen and Brush settings, none of which have resulted in anything being drawn.

      ___/
     /
    __/
   /
  ____/
  Ed Leafe

Linux Love:
unzip;strip;touch;finger;mount;fsck;more;yes;umount;sleep

···

On Apr 26, 2004, at 8:55 AM, Ed Leafe wrote:

self.dc = wx.ClientDC(self)
self.dc.SetPen(wx.Pen("black", 1, wx.SOLID))
self.dc.SetBrush(wx.RED_BRUSH)
self.dc.DrawRectangle( (50,50), (25,30) )

  The panel appears normally, but no rectangle is drawn on it.

Ed Leafe writes:

        I'm trying to do some simple drawing on a panel, and
nothing is showing up. Here's the code:

self.dc = wx.ClientDC(self)
self.dc.SetPen(wx.Pen("black", 1, wx.SOLID))
self.dc.SetBrush(wx.RED_BRUSH)
self.dc.DrawRectangle( (50,50), (25,30) )

        The panel appears normally, but no rectangle is drawn
on it.

It is being drawn, but then the panel is being painted again,
covering up your changes. You need to do this inside the
panel's paint event to make sure your rectangle always stays
visible, as when the frame resizes or some other object
temporarily obscurs it, etc.:

def __init__(self ...)
  self.pn = wx.Panel(...)
  self.pn.Bind(wx.EVT_PAINT, self.onPanelPaint)

def onPanelPaint(self, evt):
  dc = wx.ClientDC(self.pn)
  dc.SetPen(wx.Pen("black", 1, wx.SOLID))
  dc.SetBrush(wx.RED_BRUSH)
  dc.DrawRectangle( (50,50), (25,30) )

···

--
Paul

I'm using this to draw a marquee as the user drags their mouse on the panel. I'm using the same technique used in PythonCard. I had this working in wxPython 2.4, but am now having problems trying to get it work in 2.5.1.5.

      ___/
     /
    __/
   /
  ____/
  Ed Leafe
  http://leafe.com/
  http://opentech.leafe.com

···

On Apr 26, 2004, at 10:38 AM, Paul McNett wrote:

It is being drawn, but then the panel is being painted again,
covering up your changes. You need to do this inside the
panel's paint event to make sure your rectangle always stays
visible, as when the frame resizes or some other object
temporarily obscurs it, etc.:

Ed Leafe writes:

> It is being drawn, but then the panel is being painted
> again, covering up your changes. You need to do this inside
> the panel's paint event to make sure your rectangle always
> stays visible, as when the frame resizes or some other
> object temporarily obscurs it, etc.:

        I'm using this to draw a marquee as the user drags
their mouse on the panel. I'm using the same technique used
in PythonCard. I had this working in wxPython 2.4, but am now
having problems trying to get it work in 2.5.1.5.

Well, try this code. Note that if you move the drawing out of
OnPanelPaint, you will no longer see the rectangle:

import wx

class Test(wx.Frame):
  def __init__(self, parent, id, label):
    super(Test, self).__init__(parent, id, label)

    self.pn = wx.Panel(self)
    self.pn.Bind(wx.EVT_PAINT, self.onPanelPaint)
  
  def onPanelPaint(self, evt):
    dc = wx.ClientDC(self.pn)
    dc.SetPen(wx.Pen("black", 1, wx.SOLID))
    dc.SetBrush(wx.RED_BRUSH)
    dc.DrawRectangle( (50,50), (25,30) )

if __name__ == "__main__":
  app = wx.PySimpleApp()
  w = Test(None, -1, 'test')
  w.Show(True)

  app.MainLoop()

···

--
Paul

Not true. Instead, I bound EVT_LEFT_UP to the method, and the rectangle was indeed painted.

      ___/
     /
    __/
   /
  ____/
  Ed Leafe
  http://leafe.com/
  http://opentech.leafe.com

···

On Apr 26, 2004, at 12:13 PM, Paul McNett wrote:

Well, try this code. Note that if you move the drawing out of
OnPanelPaint, you will no longer see the rectangle:

Ed Leafe writes:

> Well, try this code. Note that if you move the drawing out
> of OnPanelPaint, you will no longer see the rectangle:

        Not true. Instead, I bound EVT_LEFT_UP to the method,
and the rectangle was indeed painted.

Move something on top of it, like another window, and then
reexpose it and you'll see that it is gone.

The point is that you probably had the code somewhere before the
final painting of the panel - before it was sized to the frame.
Now you have it in LEFT_UP and it is working, until the panel
gets repainted that is.

···

--
Paul

OK, I figured this out. The problem was that I was storing the wxClientDC as a property of the panel, instead of creating a new one each time through. I should have just RTFM, since the following is what is said about wxClientDC:

"A wxClientDC must be constructed if an application wishes to paint on the client area of a window from outside an OnPaint event. This should normally be constructed as a temporary stack object; don't store a wxClientDC object. To draw on a window from within OnPaint, construct a wxPaintDC object."

  It's working fine now. Thanks for your ideas!

      ___/
     /
    __/
   /
  ____/
  Ed Leafe

Linux Love:
unzip;strip;touch;finger;mount;fsck;more;yes;umount;sleep

···

On Apr 26, 2004, at 12:22 PM, Ed Leafe wrote:

Well, try this code. Note that if you move the drawing out of
OnPanelPaint, you will no longer see the rectangle:

  Not true. Instead, I bound EVT_LEFT_UP to the method, and the rectangle was indeed painted.