I’m writing a wxPython app that needs to match the appearance of an existing Windows application.
I’m trying to put Static Text and Button controls on a panel with a gradient background. Here are the ways I’ve found, but I can’t help feeling that I’m missing something. How should I draw static text and custom controls and let the background show through?
- Somehow persuade native controls not to draw the background. This applies esp. to wxStaticText
- Turn on the global system option
msw.window.no-clip-childrento let the background show through? - Pass in a repainting function that touches up the background of each
control during its onPaint Handler
2 seems easiest but I wonder if it’s turned off for a reason. Are there any performance implications to turning on the no-clip-children globally? Is there any way to turn it on just for the windows I want?
edit: Sample code and screnshots
Sorry if this is starting to look like an answer in a question. I want to know if there is a right way to do this.

#!/usr/bin/python
import wx
class GradientPanel(wx.Panel):
def __init__(self,*args,**kwargs):
wx.Panel.__init__(self,*args,**kwargs)
self.Bind(wx.EVT_PAINT,lambda e: self.paintBackground())
self.Bind(wx.EVT_ERASE_BACKGROUND,lambda e: None)
self.t=wx.StaticText(self,pos=(30,20),label="wxStaticText. Looks bad on MSW")
self.t2=MyStaticText(self,pos=(30,50), size=(300,25), label="MyStaticText. Needs ClipChildren turned off")
self.t3=MyStaticTextWithCustomBackground(self,pos=(30,80),size=(300,25), label="This Control touches up its own background",paintBackgroundToDC=self.paintBackgroundToDC)
def paintBackground(self):
dc=wx.PaintDC(self)
self.paintBackgroundToDC(self,dc)
def paintBackgroundToDC(self,ofWindow,dc=None):
r=self.GetScreenRect()
r.SetTopLeft(ofWindow.ScreenToClient(r.GetTopLeft()))
dc.GradientFillLinear(r,wx.Colour(240,240,240),wx.Colour(128,128,255),wx.SOUTH)
class MyStaticText(wx.Window):
def __init__(self,parent,label,**kwargs):
wx.Window.__init__(self,parent,**kwargs)
self.label=label
self.Bind(wx.EVT_PAINT,lambda e: self.repaint())
self.Bind(wx.EVT_ERASE_BACKGROUND,lambda e: None)
def repaint(self):
self.repaintToDC(wx.PaintDC(self))
def repaintToDC(self,dc):
dc.DrawText(self.label,0,0)
class MyStaticTextWithCustomBackground(MyStaticText):
def __init__(self,parent,label,paintBackgroundToDC=None,**kwargs):
self.paintBackgroundToDC=paintBackgroundToDC
MyStaticText.__init__(self,parent,label,**kwargs)
def repaint(self):
dc=wx.PaintDC(self)
if self.paintBackgroundToDC:
self.paintBackgroundToDC(self,dc)
MyStaticText.repaintToDC(self,dc)
if __name__ == "__main__":
#wx.SystemOptions.SetOptionInt('msw.window.no-clip-children',1)
app=wx.PySimpleApp()
frame=wx.Frame(None,title="Transparent Controls")
panel=GradientPanel(frame)
frame.Show()
app.MainLoop()
I ran into this exact problem the other day: how to display static text with a transparent background using wxPython. Here’s what I came up with:
A couple of key things:
I have noticed occasional problems where the parent panel’s background does not get invalidated when the content of the TransparentText control gets updated. It’s not consistent, and it usually works well.