wxPython: Resetting the Background Color

The last couple weeks, I’ve seen multiple people ask about resetting the color of a widget back to its original “default” color. There was at least one guy on the wxPython mailing list and another on their IRC channel that requested info on this topic. When I first looked up this issue, it was for the fellow programmer on the list who wanted to reset the background color of a panel. In my searching, I thought I had found the perfect solution:

color = wx.SystemSettings.GetColour(wx.SYS_COLOUR_BACKGROUND)
panel.SetBackgroundColour(color)

Unfortunately, that won’t work in all cases. Instead, Robin Dunn recommended using wx.NullColor instead (you can read the full thread here). According to Mr. Dunn, the reason is that (wx.NullColor) will tell wx that the widget has no specific color set and so it will use whatever the platform wants to use, which may be controlled by the active theme and may not be a solid color at all. This is a little different from using the system settings color as then wx will act as if a custom color has been set and it doesn’t care if it happens to be the same as the system color.

Thus, I created a demo application that will show you how to reset the color:

import wx
 
class MyForm(wx.Frame):
 
    def __init__(self):
        wx.Frame.__init__(self, None, wx.ID_ANY, 
                                 "Background Reset Tutorial")
 
        # Add a panel so it looks the correct on all platforms
        self.panel = wx.Panel(self, wx.ID_ANY)

        self.txt = wx.TextCtrl(self.panel)
        self.txt.SetBackgroundColour("Yellow")
        
        blueBtn = wx.Button(self.panel, 
                           label="Change Background Color")
        blueBtn.Bind(wx.EVT_BUTTON, self.onChangeBackground)
        resetBtn = wx.Button(self.panel, label="Reset")
        resetBtn.Bind(wx.EVT_BUTTON, self.onReset)
        
        topSizer = wx.BoxSizer(wx.VERTICAL)
        btnSizer = wx.BoxSizer(wx.HORIZONTAL)
        
        btnSizer.Add(blueBtn, 0, wx.ALL|wx.CENTER, 5)
        btnSizer.Add(resetBtn, 0, wx.ALL|wx.CENTER, 5)
        
        topSizer.Add(self.txt, 0, wx.ALL, 5)
        topSizer.Add(btnSizer, 0, wx.CENTER)
        self.panel.SetSizer(topSizer)

    def onChangeBackground(self, event):
        """
        Change the background color of the panel
        """
        self.panel.SetBackgroundColour("Blue")
        self.panel.Refresh()
        
    def onReset(self, event):
        """
        Reset the color of the panel to the default color
        """
        self.panel.SetBackgroundColour(wx.NullColor)
        self.txt.SetBackgroundColour(wx.NullColor)
        self.panel.Refresh()
 
# Run the program
if __name__ == "__main__":
    app = wx.PySimpleApp()
    frame = MyForm()
    frame.Show()
    app.MainLoop()

In this code, you will notice that I have set the text control with the initial background color of yellow and I allow the user to also change the panel’s background through a button event handler. The user may also “reset” the background color of both widgets by pressing the “Reset” button.

Here’s a before and after picture:

Before reset
Before reset
After reset
After reset

There’s really nothing else to say. Now you know the trick too, so if you see a newb that is struggling with this you can tell them what to do too!

This code was tested on the following:

  • Windows XP, wxPython 2.8.10.1 (msw-unicode), Python 2.5.2

Downloads

4 thoughts on “wxPython: Resetting the Background Color”

  1. Perfect advice.
    I just had this problem with Vista:

    wx.SystemSettings.GetColour(wx.SYS_COLOUR_
    BACKGROUND)

    returns a plain gray, while SetColor(wx.NullColor) gives me back the original button background (kind of gradient)

    Thanks a lot!

  2. Mauro,

    I’m glad it worked. I haven’t had a chance to try this in a “real” world program. It’s good to know that it works!

    Mike

  3. Mauro,

    I’m glad it worked. I haven’t had a chance to try this in a “real” world program. It’s good to know that it works!

    Mike

Comments are closed.