DataViewCtrl RenderText problem getting white text on dark field

Hey. I’m having a problem with the DataViewCtrl RenderText function. I’m thinking it is my problem and something silly, but I’ve been stuck with it for a bit. I’m making a program that uses a dataview control to show a text fields in ellipses in a number of colors. When I want to put white text on a dark-colored ellipse to make it readable, I am getting inconsistent results but normally, I’ll get black text. I’ve modified the DVC_CustomRenderer example’s Render function to reproduce at least on case of this. If you replace the render function with this:

    def Render(self, rect, dc, state):
        if self.value:
            # make a copy of the rect and we'll use it to track position.
            valRect = rect

            startXOffset = valRect.GetX()
            xOffset= 0 # offset to start of this ellipse
            offsetSpace = 5     # space between ellipses
            # might be multiple values in the column, split and render each into it's own ellipse
            valStr = '{}'.format(self.value)
            # split by space so we have ellipses around each word.
            valList = [x.strip() for x in valStr.split(' ')]
            print('Rendering {} to ellipses. valList:{}'.format(self.value,valList))
            for tmpVal in valList:
                # pad some spaces before and after...
                strToPrint = '  {}  '.format(tmpVal) if tmpVal else ""
                # update the rect size to the new size of this value (change it's x value to match the length)
                size = self.GetTextExtent(strToPrint)
                size += (8,8)   
                newXOffset = startXOffset+xOffset
                # we'll draw a shaded background 
				# this value is too dark for black text, I need to render the ellipse
				# in this color and have the text show in white on it.
                bgColor = [18,  92,  38]		
                if tmpVal:
                    # black pen for the outline of the box.
                    dc.SetPen(wx.Pen([0,0,0]))      #wx.TRANSPARENT_PEN #[0,0,0]
                    dc.DrawRoundedRectangle(valRect, 3)
                # now reset the pen to white for white text
                dc.SetPen(wx.Pen([255, 255, 255]))
			    # but this function will ignore that and paints the text black.
                                5,   # x-offset
                                state # wxDataViewCellRenderState flags
                xOffset += size.GetWidth() + offsetSpace
            # no value... render anyway. (behaves this way in the example...)
            tmpVal = '  {}  '.format(self.value) if self.value else ""
            self.RenderText(tmpVal, 5, rect, dc, state)
        return True

The result is:

And I think it should be showing with white text. Any help, comments or info would be greatly appreciated!

The pen is not used to set the text color, you should use dc.SetTextForeground for that.

That said, it’s possible that the native implementations may not use the dc’s currently set text foreground when rendering the text. If that’s the case then you should be able to draw the cell yourself using the dc methods instead of calling self.RenderText

1 Like

You could also experiment with using wx.RendererNative.DrawItemText which is what the default version of RenderText is using.

1 Like

Thank you! Thank you! Thank you!

Worked great. I have a hard time finding nuances like that (learning to do lol).

Also thank you for all you do for WxPython!