Transparent static text in wxPython
For my non-geek friends, feel free to bail now. This is a nerd post.
I’ve been spending a lot of time lately on a project that uses wxPython for its GUI. Yesterday, I spent about five hours trying to figure out how to have a static text widget that would have a transparent background. My application had a gradient background, and I wanted that to show through under the text.
After a bunch of Googling, I found lots of requests for such a widget, but I didn’t find any good explanations on how to do it. Fortunately, I did figure it out, and as is often the case, the solution was straightforward in hindsight. In the hope that I’ll save somebody a headache, here’s some code for a transparent static text widget:
""" Static text with transparent background """ import wx class TransparentText(wx.StaticText): def __init__(self, parent, id=wx.ID_ANY, label='', pos=wx.DefaultPosition, size=wx.DefaultSize, style=wx.TRANSPARENT_WINDOW, name='transparenttext'): wx.StaticText.__init__(self, parent, id, label, pos, size, style, name) self.Bind(wx.EVT_PAINT, self.on_paint) self.Bind(wx.EVT_ERASE_BACKGROUND, lambda event: None) self.Bind(wx.EVT_SIZE, self.on_size) def on_paint(self, event): bdc = wx.PaintDC(self) dc = wx.GCDC(bdc) font_face = self.GetFont() font_color = self.GetForegroundColour() dc.SetFont(font_face) dc.SetTextForeground(font_color) dc.DrawText(self.GetLabel(), 0, 0) def on_size(self, event): self.Refresh() event.Skip()
A couple of key things: First the style of the widget is wx.TRANSPARENT_WINDOW (all controls are windows). Second, GCDC is used in on_paint(), because the normal DC doesn’t support transparency very well.
Unfortunately, many of the other widgets in wxPython have a similar lack of transparency support, so I ended up punting and redesigning without a gradient background. However, if I want to go back in the future and create more custom transparent widgets, this approach seems viable.
You should go to Stack Overflow and respond to questions that your solution solves.
@Brian Good idea. I haven’t been active on Stack Overflow, but this is a good opportunity to start!
Doesn’t work nicely with SetLabel, but great to see how this can be done!
I am not a nerd, but glad I did not bail out.
Your solution is just what the doctor ordered (for me), and yes, 20/20 hindsight has a habit of beating most other visions. I was blitting to and fro, It works but is very convoluted compared with your solution.
Awesome. Very nice solution to something that I have seen posted numerous times. I was able to add your class to my code and it does exactly what I needed.
I love it when other do my work for me!