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()
