How can I create a StaticBitmap replacement using a panel?

I’m pulling a bitmap in from a database and I was putting it in a StaticBitmap using the SetBitmap() method. That worked fine, but I wanted to be able to capture a click on the image. I did some googling, doc reading and list archive perusing and it appears that I need to use something I can draw on (like a panel) to be able to capture the click event.

I replaced my StaticBitmap with the following object:

class imagePanel(wx.Panel):

def __init__(self, parent, size):

	wx.Panel.__init__(self, parent, wx.ID_ANY, size)

	print size

	self.buffer = wx.EmptyBitmap(size[0], size[1])

	dc = wx.BufferedDC(None, self.buffer)

	dc.SetBackground(wx.Brush(self.GetBackgroundColour()))

	dc.Clear()

	self.Bind(wx.EVT_PAINT, self.onPaint)

def SetBitmap(self, bmp):

	print 'Setting Bitmap'

	self.buffer = bmp

	self.Refresh()

def onPaint(self, e):

	print 'Painting'

	dc = wx.BufferedPaintDC(self, self.buffer)

but this is resulting in a small black square. Can anyone show me what I’m doing wrong?

Thanks!

David Ruggles

I’ve continued playing with this. I put a staticbitmap right above the panel and set it at the same time with the same bitmap. I also took a screenshot of the wrong output. code: http://pastebin.com/91Hzrf2z screenshot: http://f.imgtmp.com/JOVlo.png

I don’t understand why the staticbitmap displays the same bitmap correctly, but the dc.DrawBitmap turns it in to a tiny black square.

(for the archive, these links will only last about a day)

Thanks!

David Ruggles

···

On Thu, Aug 4, 2011 at 12:12 AM, David Ruggles thedavidfactor@gmail.com wrote:

I’m pulling a bitmap in from a database and I was putting it in a StaticBitmap using the SetBitmap() method. That worked fine, but I wanted to be able to capture a click on the image. I did some googling, doc reading and list archive perusing and it appears that I need to use something I can draw on (like a panel) to be able to capture the click event.

I replaced my StaticBitmap with the following object:

class imagePanel(wx.Panel):

def init(self, parent, size):

  wx.Panel.__init__(self, parent, wx.ID_ANY, size)
  print size
  self.buffer = wx.EmptyBitmap(size[0], size[1])
  dc = wx.BufferedDC(None, self.buffer)
  dc.SetBackground(wx.Brush(self.GetBackgroundColour()))
  dc.Clear()
  self.Bind(wx.EVT_PAINT, self.onPaint)

def SetBitmap(self, bmp):

  print 'Setting Bitmap'
  self.buffer = bmp
  self.Refresh()

def onPaint(self, e):

  print 'Painting'
  dc = wx.BufferedPaintDC(self, self.buffer)

but this is resulting in a small black square. Can anyone show me what I’m doing wrong?

Thanks!

David Ruggles

See the attached files for a working example.

In the future please attach a complete, but minimal semi-working program, not just a chunk of code.

Ray Pasco

PanelBackgroundImage.PY (3.51 KB)

Best Retriever Ever.JPG

I'm not sure why you are not seeing at least part of your image, and without a runnable sample (MakingSampleApps - wxPyWiki) it's hard to say for sure, but I do see these problems:

* If you've got this window in a sizer then you are not doing anything that will give the sizer hints on how this window should be sized. You can either change your base class to wx.PyPanel and then override DoGetBestSize, or you can call self.SetMinSize. See WindowSizeInfo - wxPyWiki

* Since you are only going to be painting a single bitmap there really isn't any need to do buffered drawing, since the whole purpose of buffering is to reduce the number of operations that draw to the screen to just one operation per paint event.

* Finally, you are "reinventing the wheel" See the wx.lib.statbmp module.

···

On 8/4/11 9:05 AM, David Ruggles wrote:

I've continued playing with this. I put a staticbitmap right above the
panel and set it at the same time with the same bitmap. I also took a
screenshot of the wrong output. code:
http://pastebin.com/91Hzrf2z screenshot: http://f.imgtmp.com/JOVlo.png

I don't understand why the staticbitmap displays the same bitmap
correctly, but the dc.DrawBitmap turns it in to a tiny black square.

(for the archive, these links will only last about a day)

--
Robin Dunn
Software Craftsman

Thank you for your patient help. I was assuming I was “reinventing the wheel” but for the life of me I wasn’t able get the right google foo to let me find the “wheel”

Thanks for the pointers!

Thanks!

David Ruggles

···

On Thu, Aug 4, 2011 at 1:23 PM, Robin Dunn robin@alldunn.com wrote:

On 8/4/11 9:05 AM, David Ruggles wrote:

I’ve continued playing with this. I put a staticbitmap right above the

panel and set it at the same time with the same bitmap. I also took a

screenshot of the wrong output. code:

http://pastebin.com/91Hzrf2z screenshot: http://f.imgtmp.com/JOVlo.png

I don’t understand why the staticbitmap displays the same bitmap

correctly, but the dc.DrawBitmap turns it in to a tiny black square.

(for the archive, these links will only last about a day)

I’m not sure why you are not seeing at least part of your image, and without a runnable sample (http://wiki.wxpython.org/MakingSampleApps) it’s hard to say for sure, but I do see these problems:

  • If you’ve got this window in a sizer then you are not doing anything that will give the sizer hints on how this window should be sized. You can either change your base class to wx.PyPanel and then override DoGetBestSize, or you can call self.SetMinSize. See http://wiki.wxpython.org/WindowSizeInfo

  • Since you are only going to be painting a single bitmap there really isn’t any need to do buffered drawing, since the whole purpose of buffering is to reduce the number of operations that draw to the screen to just one operation per paint event.

  • Finally, you are “reinventing the wheel” See the wx.lib.statbmp module.

Robin Dunn

Software Craftsman

http://wxPython.org

To unsubscribe, send email to wxPython-users+unsubscribe@googlegroups.com

or visit http://groups.google.com/group/wxPython-users?hl=en

Based on my research it looks like wx.lib.statbmp should be (or is designed to be) a drop-in replacement for StaticBitmap.

Because of the way I was using StaticBitmap I found two discrepancies, which I fixed, but I’m not sure I fixed them correctly.

  1. If you set a size for a StaticBitmap, using SetBitmap doesn’t change the size

  2. If you call SetBitmap(wx.NullBitmap) on a StaticBitmap it clears the bitmap

Here’s the class and I’ve noted my changes:

class GenStaticBitmap(wx.PyControl):

labelDelta = 1

def __init__(self, parent, ID, bitmap,

             pos = wx.DefaultPosition, size = wx.DefaultSize,

             style = 0,

             name = "genstatbmp"):

    self._fixedsize = (size != wx.DefaultSize) <<<<<<< If a size is specified, make it a fixed size

    if not style & wx.BORDER_MASK:

        style = style | wx.BORDER_NONE

    wx.PyControl.__init__(self, parent, ID, pos, size, style,

                         wx.DefaultValidator, name)

    self._bitmap = bitmap

    self.InheritAttributes()

    self.SetInitialSize(size)

    self.Bind(wx.EVT_ERASE_BACKGROUND, self.OnEraseBackground)

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

def SetBitmap(self, bitmap):

    self._bitmap = bitmap

    if not self._fixedsize:                                            <<<<<<< Only change the size if it wasn't specified on init

        self.SetInitialSize( (bitmap.GetWidth(), bitmap.GetHeight()) ) <<<<<<<

    self.Refresh()

def GetBitmap(self):

    return self._bitmap



def DoGetBestSize(self):

    """

    Overridden base class virtual.  Determines the best size of the

    control based on the bitmap size.

    """

    return wx.Size(self._bitmap.GetWidth(), self._bitmap.GetHeight())

def AcceptsFocus(self):

    """Overridden base class virtual."""

    return False

def GetDefaultAttributes(self):

    """

    Overridden base class virtual.  By default we should use

    the same font/colour attributes as the native StaticBitmap.

    """

    return wx.StaticBitmap.GetClassDefaultAttributes()



def ShouldInheritColours(self):

    """

    Overridden base class virtual.  If the parent has non-default

    colours then we want this control to inherit them.

    """

    return True



def OnPaint(self, event):

    dc = wx.PaintDC(self)

    if self._bitmap:

        dc.DrawBitmap(self._bitmap, 0, 0, True)

    else:          <<<<<<<

        dc.Clear() <<<<<<< This will clear the image if wx.NullBitmap is passed in                        

def OnEraseBackground(self, event):

    pass

Thanks!

David Ruggles

···

On Thu, Aug 4, 2011 at 1:28 PM, David Ruggles thedavidfactor@gmail.com wrote:

Thank you for your patient help. I was assuming I was “reinventing the wheel” but for the life of me I wasn’t able get the right google foo to let me find the “wheel”

Thanks for the pointers!

Thanks!

David Ruggles

On Thu, Aug 4, 2011 at 1:23 PM, Robin Dunn robin@alldunn.com wrote:

On 8/4/11 9:05 AM, David Ruggles wrote:

I’ve continued playing with this. I put a staticbitmap right above the

panel and set it at the same time with the same bitmap. I also took a

screenshot of the wrong output. code:

http://pastebin.com/91Hzrf2z screenshot: http://f.imgtmp.com/JOVlo.png

I don’t understand why the staticbitmap displays the same bitmap

correctly, but the dc.DrawBitmap turns it in to a tiny black square.

(for the archive, these links will only last about a day)

I’m not sure why you are not seeing at least part of your image, and without a runnable sample (http://wiki.wxpython.org/MakingSampleApps) it’s hard to say for sure, but I do see these problems:

  • If you’ve got this window in a sizer then you are not doing anything that will give the sizer hints on how this window should be sized. You can either change your base class to wx.PyPanel and then override DoGetBestSize, or you can call self.SetMinSize. See http://wiki.wxpython.org/WindowSizeInfo

  • Since you are only going to be painting a single bitmap there really isn’t any need to do buffered drawing, since the whole purpose of buffering is to reduce the number of operations that draw to the screen to just one operation per paint event.

  • Finally, you are “reinventing the wheel” See the wx.lib.statbmp module.

Robin Dunn

Software Craftsman

http://wxPython.org

To unsubscribe, send email to wxPython-users+unsubscribe@googlegroups.com

or visit http://groups.google.com/group/wxPython-users?hl=en