wxPyGridCellRenderer

The cell renderer allows you to customize the display of a particular data type within the grid. For instance, it allows you to display a "colour" data type as a swatch of colour, rather than as a mere plain-text label. The class has a very simple API, using a standard wxDC for drawing into the cell's rectangle. A secondary function of the renderer is the determination of the "best size" for the cell.

Example of use

from wxPython.wx import *
from wxPython.grid import *
from wxprop import basetableworker

class BaseViewer( basetableworker.BaseTableWorker, wxPyGridCellRenderer):
        """Base class for editors"""
        BACKGROUND_SELECTED = wxSystemSettings_GetColour( wxSYS_COLOUR_HIGHLIGHT )
        TEXT_SELECTED = wxSystemSettings_GetColour( wxSYS_COLOUR_HIGHLIGHTTEXT )
        BACKGROUND = wxSystemSettings_GetColour( wxSYS_COLOUR_WINDOW  )
        TEXT = wxSystemSettings_GetColour( wxSYS_COLOUR_WINDOWTEXT  )

        ### Customisation points
        def GetValueAsText( self, row, col ):
                """Customisation Point: Retrieve the current value for row,col as a text string"""
                return str( self.GetCurrentTableValue( row, col ) )
        def Draw(self, grid, attr, dc, rect, row, col, isSelected):
                """Customisation Point: Draw the data from grid in the rectangle with attributes using the dc"""
                self.Clip(dc, rect)
                self.Background( grid, attr, dc, rect, row, col, isSelected)
                try:
                        value = self.GetValueAsText( row, col )
                        dc.SetFont( wxNORMAL_FONT )
                        return self.SimpleText( value, attr, dc, rect, isSelected)
                finally:
                        self.Unclip(dc)
        def GetBestSize(self, grid, attr, dc, row, col):
                """Customisation Point: Determine the appropriate (best) size for the control, return as wxSize

                Note: You _must_ return a wxSize object.  Returning a two-value-tuple
                won't raise an error, but the value won't be respected by wxPython.
                """
                x,y = dc.GetTextExtent( self.GetValueAsText( row, col ) )
                # note that the two-tuple returned by GetTextExtent won't work,
                # need to give a wxSize object back!
                return wxSize( x,y )


        ### Utility methods
        def SimpleText( self, value, attr, dc, rect, isSelected):
                """Draw a simple text label in appropriate colours with background

                Uses the system settings at application load to draw a rectangle
                (rect) in either system window background or system selected window
                background.  Then draws the string "value" using either selected
                text or normal text colours.
                """
                previousText = dc.GetTextForeground()
                if isSelected:
                        dc.SetTextForeground( self.TEXT_SELECTED )
                else:
                        dc.SetTextForeground( self.TEXT )
                try:
                        dc.DrawText( value, rect.x+2,rect.y+2 )
                finally:
                        dc.SetTextForeground( previousText )

        def Background( self, grid, attr, dc, rect, row, col, isSelected):
                """Draw an appropriate background based on selection state"""
                if isSelected:
                        dc.SetBrush( wxBrush( self.BACKGROUND_SELECTED, wxSOLID) )
                else:
                        dc.SetBrush( wxBrush( self.BACKGROUND, wxSOLID) )
                try:
                        dc.SetPen(wxTRANSPARENT_PEN)
                        dc.DrawRectangle( rect.x, rect.y, rect.width, rect.height )
                finally:
                        dc.SetPen( wxNullPen )
                        dc.SetBrush( wxNullBrush )
                

        def Clip( self, dc, rect ):
                """Setup the clipping rectangle"""
                dc.SetClippingRegion( rect.x, rect.y, rect.width, rect.height )
        def Unclip( self, dc ):
                """Destroy the clipping rectangle"""
                dc.DestroyClippingRegion( )

Back to the wxGrid Manual


Can anyone add some more code to the above example? I mean, it's nice to see the code of a proper renderer, but what I'm missing is the code to "attach" this renderer to a wxGrid object. A renderer on its own won't do much, will it?

-- Sybren Stüvel

There are examples in the wxPython demo's, download from http://www.wxpython.org/download.php

-- Martijn

wxPyGridCellRenderer (last edited 2008-03-11 10:50:18 by localhost)

NOTE: To edit pages in this wiki you must be a member of the TrustedEditorsGroup.