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 AppFrame( wx.Frame )  :
   4 
   5     def __init__( self )  :
   6 
   7         wx.Frame.__init__( self, None, title="Am I transparent?",
   8                            style=wx.DEFAULT_FRAME_STYLE | wx.STAY_ON_TOP )
   9         self.SetClientSize( (300, 300) )
  10 
  11         self.alphaValue = 255
  12         self.alphaIncrement = -4
  13 
  14         pnl = wx.Panel( self )
  15         self.stTxt = wx.StaticText( pnl, -1, str( self.alphaValue ), (25, 25) )
  16         self.stTxt.SetFont( wx.Font( 18, wx.SWISS, wx.NORMAL, wx.NORMAL ) )
  17 
  18         self.changeAlpha_timer = wx.Timer( self )
  19         self.changeAlpha_timer.Start( 50 )       # 20 changes per second
  20         self.Bind( wx.EVT_TIMER, self.ChangeAlpha )
  21 
  22         self.Bind( wx.EVT_CLOSE, self.OnCloseWindow )
  23 
  24     #end AppFrame class
  25 
  26     #--------------------------------------------------------
  27 
  28     def ChangeAlpha( self, evt )  :
  29         """ The term "alpha" means variable transparency
  30               as opposed to a "mask" which is binary transparency.
  31               alpha == 255 :  fully opaque
  32               alpha ==   0 :  fully transparent (mouse is ineffective!)
  33 
  34             Only top-level controls can be transparent; no other controls can.
  35             This is because they are implemented by the OS, not wx.
  36         """
  37 
  38         self.alphaValue += self.alphaIncrement
  39         if (self.alphaValue) <= 0 or (self.alphaValue >= 255) :
  40 
  41             # Reverse the increment direction.
  42             self.alphaIncrement = -self.alphaIncrement
  43 
  44             if self.alphaValue <= 0 :
  45                 self.alphaValue = 0
  46 
  47             if self.alphaValue > 255 :
  48                 self.alphaValue = 255
  49         #end if
  50 
  51         self.stTxt.SetLabel( str( self.alphaValue ) )
  52 
  53         # Note that we no longer need to use ctypes or win32api to
  54         # make transparent windows, however I'm not removing the
  55         # MakeTransparent code from this sample as it may be helpful
  56         # to someone for other uses, someday.
  57 
  58         #self.MakeTransparent( self.alphaValue )
  59 
  60         # Instead, just call the SetTransparent() method
  61         self.SetTransparent( self.alphaValue )      # Easy !
  62 
  63     #end ChangeAlpha def
  64 
  65     #--------------------------------------------------------
  66 
  67     def OnCloseWindow( self, evt ) :
  68 
  69         self.changeAlpha_timer.Stop()
  70         del self.changeAlpha_timer       # avoid a memory leak
  71         self.Destroy()
  72 
  73     #-----------------------------------------------------
  74 
  75     def MakeTransparent( self, amount ) :
  76         """
  77         This is how the method SetTransparent() is implemented
  78             on all MS Windows platforms.
  79         """
  80         import os
  81         if os.name == 'nt' :  # could substitute: sys.platform == 'win32'
  82 
  83             hwnd = self.GetHandle()
  84             try :
  85                 import ctypes   # DLL library interface constants' definitions
  86                 _winlib = ctypes.windll.user32    # create object to access DLL file user32.dll
  87                 style = _winlib.GetWindowLongA( hwnd, 0xffffffecL )
  88                 style |= 0x00080000
  89                 _winlib.SetWindowLongA( hwnd, 0xffffffecL, style )
  90                 _winlib.SetLayeredWindowAttributes( hwnd, 0, amount, 2 )
  91 
  92             except ImportError :
  93 
  94                 import win32api, win32con, winxpgui
  95                 _winlib = win32api.LoadLibrary( "user32" )
  96                 pSetLayeredWindowAttributes = win32api.GetProcAddress(
  97                     _winlib, "SetLayeredWindowAttributes" )
  98                 if pSetLayeredWindowAttributes == None :
  99                     return
 100                 exstyle = win32api.GetWindowLong( hwnd, win32con.GWL_EXSTYLE )
 101                 if 0 == ( exstyle & 0x80000 ) :
 102                     win32api.SetWindowLong( hwnd,
 103                                            win32con.GWL_EXSTYLE,
 104                                            exstyle | 0x80000 )
 105                 winxpgui.SetLayeredWindowAttributes( hwnd, 0, amount, 2 )
 106         else :
 107             print '####  OS Platform must be MS Windows'
 108             self.Destroy()
 109         #end if
 110     #end MakeTransparent def
 111 
 112 #end AppFrame class
 113 
 114 #=======================================================
 115 
 116 if __name__ == '__main__' :
 117 
 118     app = wx.App( False )
 119     frm = AppFrame()
 120     frm.Show()
 121     app.MainLoop()

Frame_Alpha.png

--RobinDunn

Transparent Frames (last edited 2011-07-18 21:29:31 by pool-71-244-98-82)

NOTE: To edit pages in this wiki you must be a member of the TrustedEditorsGroup.