I’m doing a 3 part series on using wxPython and PyWin32 to capture output from a running OpenVPN session.
I use OpenVPN to connect to PCs at work. I noticed that our current method of launching OpenVPN was in a console window so that one could monitor the program’s output. If the user happened to close said window, it would end the VPN session. I thought this was dumb, so I decided that I would try wrapping the interface using wxPython in such a way that I can minimize it to the system tray and bring it back up on demand to check the output if I was having an issue. If you want to follow along, then you’ll need the following:
Got all those? Ok. Let’s continue. To begin, create a folder to hold your scripts. We’ll actually need a couple to do this right.
First, we’re going to create a system tray icon.
Step 1: Pick an icon (I used one from the Tamarin set)
Step 2: Once you have the icon, we’ll use a wxPython utility called img2py that will convert the icon or picture into a python file. It can be found in your Python folder after you’ve installed wxPython: \\path\to\Python25\Lib\site-packages\wx-2.8-msw-unicode\wx\tools (adjust as necessary for your system)
Step 3: Move the icon file to the directory in step 2 and open a command window by clicking Start, Run, and type cmd. Navigate to the directory above (using the cd command) and run the following: python img2py.py -i myIcon.ico icon.py
Step 4: Once that’s done, copy the icon.py file to the the folder you created to hold your scripts. This will be coupled with some code that handles the iconization and right-click menus.
Now we’ll create the logic needed for the system tray icon to respond to mouse events. I found some code in the wxPython Demo that did most of what I did. So I copied it and modified it slightly to fit my needs. You can see the end result below:
import wx from vpnIcon import getIcon class VPNIconCtrl(wx.TaskBarIcon): TBMENU_RESTORE = wx.NewId() TBMENU_CLOSE = wx.NewId() TBMENU_CHANGE = wx.NewId() def __init__(self, frame): wx.TaskBarIcon.__init__(self) self.frame = frame # Set the image tbIcon = getIcon() # Give the icon a tooltip self.SetIcon(tbIcon, "VPN Status") self.imgidx = 1 # bind some events self.Bind(wx.EVT_TASKBAR_LEFT_DCLICK, self.OnTaskBarActivate) self.Bind(wx.EVT_MENU, self.OnTaskBarActivate, id=self.TBMENU_RESTORE) self.Bind(wx.EVT_MENU, self.OnTaskBarClose, id=self.TBMENU_CLOSE) def CreatePopupMenu(self): """ This method is called by the base class when it needs to popup the menu for the default EVT_RIGHT_DOWN event. Just create the menu how you want it and return it from this function, the base class takes care of the rest. """ menu = wx.Menu() menu.Append(self.TBMENU_RESTORE, "View Status") menu.AppendSeparator() menu.Append(self.TBMENU_CLOSE, "Close Program") return menu def OnTaskBarActivate(self, evt): if self.frame.IsIconized(): self.frame.Iconize(False) if not self.frame.IsShown(): self.frame.Show(True) self.frame.Raise() def OnTaskBarClose(self, evt): self.Destroy() self.frame.Close()
Next time, we’ll go over the win32 code you’ll need to know and in the final piece, we’ll create the GUI and put the rest of the pieces together.