MarcoTalin12
MarcoTalin12

Reputation: 31

wx.grid isn't loading images that I'm trying to enter into cells

I'm building a program that will function as a viewer for Pokemon Cards in order to learn & practice wxPython. I've been using wx.grid to build the database explorer, and I'm trying to add the images of the cards into one of the columns, but the images don't seem to be loading.

I'm doing this by making my own instance of the GridCellRenderer. I copied code from the answer to this question: wx.grid.Grid doesn't load image. However, the image still doesn't load, and when I run the program in Debug mode, the Draw function never gets called. I know the images can be read because I can load them into the window in other ways.

I don't really understand the renderer classes in wx.grid, so maybe there's just something I'm missing, but I can't figure out for the life of me what that would be. Can someone help me figure out what's wrong?

import wx
import wx.grid as wxGrid

import pandas as pd


# App Startup Control
class MainApp(wx.App):
    def OnInit(self):
        MainFrame().Show(True)
        return True


# Window Builder
class MainFrame(wx.Frame):
    def __init__(self):
        wx.Frame.__init__(self, None, title='Pokemon Cards', size=(1080, 720))
        self.Centre()
        self.SetBackgroundColour('Green')

        # Main Sizer
        mainSizer = wx.BoxSizer(wx.VERTICAL)

        # Table Base Panel
        tableBasePanel = wx.Panel(self)
        tableBasePanel.SetBackgroundColour('Yellow')

        # Table Sizer
        tableSizer = wx.BoxSizer(wx.HORIZONTAL)


        # Build Window
        self.SetSizer(mainSizer)
        mainSizer.Add(tableBasePanel, 1, wx.ALL | wx.EXPAND, 5)
        tableBasePanel.SetSizer(tableSizer)
        tableSizer.Add(CardTable(tableBasePanel))


# Grid Builder
class CardTable(wxGrid.Grid):
    def __init__(self, parent):
        wxGrid.Grid.__init__(self, parent)
        self.parent = parent

        # Load the data from the csv to a dataframe
        self.data = pd.read_csv('Card Database.csv', na_filter=False)

        # Only load the first 20 rows of the dataframe
        self.LoadRows(0, 20)
    
    # Loads the selected rows from the dataframe to the grid 
    def LoadRows(self, start, end):
        self.SetTable(CardTableSource(self.data.iloc[start:end]), takeOwnership=True)

        # Initial Settings
        self.HideRowLabels()
        self.DisableDragColSize()
        self.DisableCellEditControl()

        # Set Column Sizes
        self.AutoSizeColumns()

        # Set the picture column size to 200
        self.SetColSize(1, 200)

        # Set the description column sizes to 300
        eff1Col = self.data.columns.get_loc('Effect 1')
        for iCol in range(eff1Col, eff1Col + 7):
            self.SetColSize(iCol, 300)

        # Add the images to each row
        for iRow in range(end-start):
            # Use the text in the picture column to get the filename of the image
            imgName = self.GetCellValue(iRow, 1)
            imgPath = 'Card Images/' + imgName

            img = wx.Bitmap(imgPath, wx.BITMAP_TYPE_ANY)

            self.SetCellValue(iRow, 1, '')
            self.SetRowSize(iRow, 280)

            # Set the renderer for the picture cell
            self.SetCellRenderer(iRow, 1, CardImageRenderer(img))


# For loading the card image
class CardImageRenderer(wxGrid.GridCellRenderer):
    def __init__(self, img):
        wxGrid.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)
        dc.Blit(rect.x, rect.y, 200, 280, image, 0, 0, wx.COPY, True)


# For converting the dataframe to the grid source
class CardTableSource(wxGrid.GridTableBase):
    def __init__(self, data=None):
        wxGrid.GridTableBase.__init__(self)
        self.headerRows = 1

        if data is None:
            data = pd.DataFrame()
        self.data = data

    def GetNumberRows(self):
        return self.data.shape[0]

    def GetNumberCols(self):
        return self.data.shape[1]

    def GetValue(self, row, col):
        return self.data.iloc[row, col]

    def SetValue(self, row, col, value):
        self.data.iat[row, col] = value

    def GetColLabelValue(self, col):
        return str(self.data.columns[col])

    def GetTypeName(self, row, col):
        return wxGrid.GRID_VALUE_STRING

    def GetAttr(self, row, col, prop):
        return wxGrid.GridCellAttr()


MainApp().MainLoop()

Upvotes: 0

Views: 65

Answers (0)

Related Questions