[Solved] How to remove styling in TextCtrl?

I want to remove the style of a previously styled text in a TextCtrl and return it to the default style. In the TextCtrl demo I changed the line 63

        t4.SetStyle(44, 47, wx.TextAttr("RED", "YELLOW"))

(this line turns the word “red” to red on yellow)
to

        default_style = t4.GetDefaultStyle()
        t4.SetStyle(44, 47, wx.TextAttr("RED", "YELLOW"))
        t4.SetStyle(45, 46, default_style)

where I thought, the last line will turn the “e” in the word “red” back to black on white. It does not.

How do I remove an already existing styling (replace it with the default styling)?

When I stepped through the code in debug, I noticed that all the colours in default_style were set to wx.Colour(-1, -1, -1, 255) which is wx.NullColour.

I found that if I explicitly set the default style, after creating the TextCtrl e.g.

        t4.SetDefaultStyle(wx.TextAttr(wx.BLACK, wx.WHITE))

then the subsequent call to t4.GetDefaultStyle() did return the correct colours and the call to SetStyle() did change the colour of the “e”, as required

I also noticed this…

How would your approach behave, if the default text colour is not black on white? That’s the reason, why I got the default style with GetDefaultStyle() and did not hardcode it.

I was also wondering about that.

I did some more experiments and noticed that default_style.Flags was set to zero.

That made me wonder if calling:

default_style.SetFlags(wx.TEXT_ATTR_TEXT_COLOUR|wx.TEXT_ATTR_BACKGROUND_COLOUR)

before calling t4.SetStyle(45, 46, default_style) would work. Unfortunately, it didn’t.

Would this be feasible:

        default_style = t4.GetDefaultStyle()
        tc = default_style.GetTextColour()
        if tc == wx.NullColour:
            tc = t4.GetForegroundColour()
        bc = default_style.GetBackgroundColour()
        if bc == wx.NullColour:
            bc = t4.GetBackgroundColour()
        t4.SetStyle(44, 47, wx.TextAttr("RED", "YELLOW"))
        t4.SetStyle(45, 46, wx.TextAttr(tc, bc))

That works. But I did not test it with non-default colour schemes.

I do it as follows:

        default_style = self.GetDefaultStyle()
        default_style = wx.TextAttr(
            default_style.GetTextColour() or self.GetForegroundColour(),
            default_style.GetBackgroundColour() or self.GetBackgroundColour(),
        )
        t4.SetStyle(44, 47, wx.TextAttr("RED", "YELLOW"))
        t4.SetStyle(45, 46, wx.TextAttr(tc, bc))

Thanks!

This does not affect your solution, but I need to correct what I said earlier about the colour values in the default style being set to wx.NullColour.

If the default style has not been explicitly set, the colours in the wx.TextAttr returned by GetDefaultStyle() are actually set to different wx.Colour objects with the same parameter values as wx.NullColour, but are not set to the wx.NullColour object itself.

They do return True for equality with wx.NullColour, but return False for identity with wx.NullColour.

Can’t you use .IsOk() instead?

I think in the context of GetDefaultStyle() it would probably work.

However, I came across an anomaly that happens if you explicitly create a wx.Colour(-1, -1, -1, 255) object, as in c3 in the following example:

>>> import wx
>>> c1 = wx.NullColour
>>> c1
wx.Colour(-1, -1, -1, 255)
>>> c1.IsOk()
False
>>> 
>>> c2 = wx.Colour()
>>> c2
wx.Colour(-1, -1, -1, 255)
>>> c2.IsOk()
False
>>> 
>>> c3 = wx.Colour(-1, -1, -1, 255)
>>> c3
wx.Colour(255, 255, 255, 255)
>>> c3.IsOk()
True
>>> 

EDIT: see also Robin’s comment at: Inconsistencies when instantiation wxColour and comparison to None (and maybe others too) · Issue #600 · wxWidgets/Phoenix · GitHub