pythonwxpythonwxgrid

wx.grid.Grid doesn't load image


I'm trying to use a code in this tutorial, but the result is a grayed cell and no image in the cell (see screenshot). It's been days since I started looking for a solution to add an image to a grid cell and I find this solution the least complicated so far, but it won't work for me. Please, can someone help me with this issue so I can move on with my project? It would be greatly appreciated. Thank you.

Here is the code:

import wx
import wx.grid
class MyApp(wx.App):
    def OnInit(self):
        frame = wx.Frame(None, -1, title = "wx.Grid - Bitmap example")
        grid = wx.grid.Grid(frame)
        grid.CreateGrid(1,1)
        img = wx.Bitmap(r"E:\Dropbox2\Dropbox\Ubot\Ubot\Python\Magnify\Tkinter Magnify\Tests\python-logo.png", wx.BITMAP_TYPE_PNG)
        imageRenderer = MyImageRenderer(img)
        grid.SetCellRenderer(0,0,imageRenderer)
        grid.SetColSize(0,img.GetWidth()+2)
        grid.SetRowSize(0,img.GetHeight()+2)
        frame.Show(True)
        return True

class MyImageRenderer(wx.grid.PyGridCellRenderer):
    def __init__(self, img):
        wx.grid.PyGridCellRenderer.__init__(self)
        self.img = img
    def Draw(self, grid, attr, dc, rect, row, col, isSelected):

        image = wx.MemoryDC()
        image.SelectObject(self.img)
        dc.SetBackgroundMode(wx.SOLID)
        if isSelected:
            dc.SetBrush(wx.Brush(wx.BLUE, wx.SOLID))
            dc.SetPen(wx.Pen(wx.BLUE, 1, wx.SOLID))
        else:
            dc.SetBrush(wx.Brush(wx.WHITE, wx.SOLID))
            dc.SetPen(wx.Pen(wx.WHITE, 1, wx.SOLID))
        dc.DrawRectangleRect(rect)
        width, height = self.img.GetWidth(), self.img.GetHeight()
        if width > rect.width-2:
            width = rect.width-2
        if height > rect.height-2:
                height = rect.height-2
        dc.Blit(rect.x+1, rect.y+1, width, height, image, 0, 0, wx.COPY, True)

app = MyApp(0)
app.MainLoop()

And the result I get:

enter image description here

You can use this image for tests:

enter image description here


Solution

  • I don't know if you are running this in an IDE but if you run it on the command line, you will see all of the warnings and errors. i.e.

    wxPyDeprecationWarning: Using deprecated class. Use GridCellRenderer instead.
      wx.grid.PyGridCellRenderer.__init__(self)
    Traceback (most recent call last):
      File "20190519.py", line 30, in Draw
        dc.DrawRectangleRect(rect)
    AttributeError: 'PaintDC' object has no attribute 'DrawRectangleRect'
    

    Acting on these, because the example is old and outdated, we can replace PyGridCellRenderer with GridCellRenderer and dump the dc.DrawRectangleRect(rect) line altogether. if the function doesn't exist, try not using it, then look for an alternative if that doesn't work.

    Edit: that line should have been dc.DrawRectangle(rect)

    We end up with this:

    import wx
    import wx.grid
    class MyApp(wx.App):
        def OnInit(self):
            frame = wx.Frame(None, -1, title = "wx.Grid - Bitmap example")
            grid = wx.grid.Grid(frame)
            grid.CreateGrid(2,2)
            img = wx.Bitmap("wxPython.jpg", wx.BITMAP_TYPE_ANY)
            imageRenderer = MyImageRenderer(img)
            grid.SetCellRenderer(0,0,imageRenderer)
            grid.SetColSize(0,img.GetWidth()+2)
            grid.SetRowSize(0,img.GetHeight()+2)
            frame.Show(True)
            return True
    
    class MyImageRenderer(wx.grid.GridCellRenderer):
        def __init__(self, img):
            wx.grid.GridCellRenderer.__init__(self)
            self.img = img
        def Draw(self, grid, attr, dc, rect, row, col, isSelected):
            image = wx.MemoryDC()
            image.SelectObject(self.img)
            dc.SetBackgroundMode(wx.SOLID)
            if isSelected:
                dc.SetBrush(wx.Brush(wx.BLUE, wx.SOLID))
                dc.SetPen(wx.Pen(wx.BLUE, 1, wx.SOLID))
            else:
                dc.SetBrush(wx.Brush(wx.WHITE, wx.SOLID))
                dc.SetPen(wx.Pen(wx.WHITE, 1, wx.SOLID))
            dc.DrawRectangle(rect)
            width, height = self.img.GetWidth(), self.img.GetHeight()
            if width > rect.width-2:
                width = rect.width-2
            if height > rect.height-2:
                height = rect.height-2
            dc.Blit(rect.x+1, rect.y+1, width, height, image, 0, 0, wx.COPY, True)
    
    app = MyApp(0)
    app.MainLoop()
    

    Which gives us this:

    enter image description here

    A full set of downloadable documentation is available here: https://extras.wxpython.org/wxPython4/extras/4.0.4/wxPython-docs-4.0.4.tar.gz
    The Demos are here:
    https://extras.wxpython.org/wxPython4/extras/4.0.4/wxPython-demo-4.0.4.tar.gz