Transparent Top-level Windows

Top level windows in wx (frames, dialogs, etc.) have a new SetTransparent method that will make the window transparent if the platform supports it. Out of the box Windows 2000 and later will support it, as well as OS X. On *nix you need to be running an X Server that supports the composite extension, have that extension loaded, and also be running a compositing manager. (Basically if you can make other windows be truly transparent, and not just redrawing the desktop background within the window, then it should be supported for wx Apps too.)

Here is an example of how to do it.

   1 import wx
   2 
   3 class Frame(wx.Frame):
   4     def __init__(self):
   5         wx.Frame.__init__(self, None, title="Am I transparent?")
   6         self.amount = 255
   7         self.delta = -3
   8 
   9         p = wx.Panel(self)
  10         self.st = wx.StaticText(p, -1, str(self.amount), (25,25))
  11         self.st.SetFont(wx.Font(18, wx.SWISS, wx.NORMAL, wx.NORMAL))
  12 
  13         self.timer = wx.Timer(self)
  14         self.timer.Start(25)
  15         self.Bind(wx.EVT_TIMER, self.AlphaCycle)
  16 
  17         self.Bind(wx.EVT_CLOSE, self.OnCloseWindow)
  18 
  19 
  20     def OnCloseWindow(self, evt):
  21         self.timer.Stop()
  22         del self.timer
  23         self.Destroy()
  24 
  25 
  26     def AlphaCycle(self, evt):
  27         self.amount += self.delta
  28         if self.amount == 0 or self.amount == 255:
  29             self.delta = -self.delta
  30         self.st.SetLabel(str(self.amount))
  31 
  32         # Note that we no longer need to use ctypes or win32api to
  33         # make transparent windows, however I'm not removing the
  34         # MakeTransparent code from this sample as it may be helpful
  35         # for somebody someday.
  36         #self.MakeTransparent(self.amount)
  37 
  38         # Instead we'll just call the SetTransparent method
  39         self.SetTransparent(self.amount)
  40 
  41 
  42     def MakeTransparent(self, amount):
  43         hwnd = self.GetHandle()
  44         try:
  45             import ctypes
  46             _winlib = ctypes.windll.user32
  47             style = _winlib.GetWindowLongA(hwnd, 0xffffffecL)
  48             style |= 0x00080000
  49             _winlib.SetWindowLongA(hwnd, 0xffffffecL, style)
  50             _winlib.SetLayeredWindowAttributes(hwnd, 0, amount, 2)
  51 
  52         except ImportError:
  53             import win32api, win32con, winxpgui
  54             _winlib = win32api.LoadLibrary("user32")
  55             pSetLayeredWindowAttributes = win32api.GetProcAddress(
  56                 _winlib, "SetLayeredWindowAttributes")
  57             if pSetLayeredWindowAttributes == None:
  58                 return
  59             exstyle = win32api.GetWindowLong(hwnd, win32con.GWL_EXSTYLE)
  60             if 0 == (exstyle & 0x80000):
  61                 win32api.SetWindowLong(hwnd,
  62                                        win32con.GWL_EXSTYLE,
  63                                        exstyle | 0x80000)
  64             winxpgui.SetLayeredWindowAttributes(hwnd, 0, amount, 2)
  65 
  66 
  67 
  68 app = wx.App(False)
  69 frm = Frame()
  70 frm.Show()
  71 app.MainLoop()

--RobinDunn

Transparent Frames (last edited 2008-03-11 10:50:26 by localhost)