Reputation: 249
I am new to python and wxPython and currently working on a small (linux-only targeted) script which features a tray icon (task bar icon) and a main window (Frame).
I am realizing an issue right now which i am not sure how to handle.
I tried to slimdown the code for this post as good as i can, hope it helps.
import wx
TRAY_TOOLTIP = 'demo'
TRAY_ICON = 'gfx/core/bt_appIcon_16.png'
appName = 'demo'
windowWidth=350
windowHeight=200
class MyFrame(wx.Frame):
def __init__(self, parent, title):
wx.Frame.__init__(self, parent, title=title, size=(windowWidth,windowHeight), style=wx.NO_BORDER) # Frame without borders
self.SetSizeHintsSz( wx.Size( windowWidth,windowHeight ), wx.Size( windowWidth,windowHeight ) ) # forcing min and max size to same values - prevents resizing option
appIcon = wx.Icon('gfx/core/bt_appIcon_16.png', wx.BITMAP_TYPE_PNG)
self.SetIcon(appIcon) # set an application icon
# Preference button of main ui
img_preferences = wx.Bitmap('gfx/core/bt_prefs_16.png', wx.BITMAP_TYPE_BMP)
self.bt_preferences = wx.BitmapButton(self, id = wx.ID_ANY, style=wx.NO_BORDER, bitmap = img_preferences, size = (img_preferences.GetWidth()+10, img_preferences.GetHeight()+10))
self.bt_preferences.SetLabel('Preferences')
bSizer1 = wx.BoxSizer( wx.VERTICAL ) # define layout container
bSizer1.Add( self.bt_preferences, 0, wx.ALIGN_RIGHT, 100) # preferences
self.SetSizer( bSizer1 )
self.Center() # open window centered
self.bt_preferences.Bind(wx.EVT_BUTTON, self.OnClicked)
self.Show(True) # show main UI
def OnClickedOptionButton(self, event):
self.launchExternalApplication()
def OnClicked(self, event):
btn = event.GetEventObject().GetLabel()
if (btn =='Preferences'):
print('clicked preference button in main-window/frame')
def create_menu_item(menu, label, func):
item = wx.MenuItem(menu, -1, label)
menu.Bind(wx.EVT_MENU, func, id=item.GetId())
menu.AppendItem(item)
return item
class TaskBarIcon(wx.TaskBarIcon, MyFrame):
def __init__(self, frame):
self.frame = frame
super(TaskBarIcon, self).__init__()
self.set_icon(TRAY_ICON)
self.Bind(wx.EVT_TASKBAR_LEFT_DOWN, self.on_left_down)
def CreatePopupMenu(self):
menu = wx.Menu()
create_menu_item(menu, 'Preferences', self.openPrefsFromMenu)
create_menu_item(menu, 'Exit', self.on_exit)
return menu
def set_icon(self, path):
icon = wx.IconFromBitmap(wx.Bitmap(path))
self.SetIcon(icon, TRAY_TOOLTIP)
def on_left_down(self, event):
print('on_left_down of tray icon')
# NEED HELP HERE
# should check if main-window is visible or not
# then toggle it
def openPrefsFromMenu(self, event):
print('open prefs from menu')
def on_exit(self, event):
wx.CallAfter(self.Destroy) # close the tray icon
self.frame.Close()
# AND SOME MORE HELP HERE
# should close the main UI as well
#exit()
class App(wx.App):
def OnInit(self):
frame=wx.Frame(None)
self.SetTopWindow(frame)
TaskBarIcon(frame)
return True
def main():
app = App(False)
frame = MyFrame(None, appName)
app.MainLoop()
if __name__ == '__main__':
main()
Upvotes: 0
Views: 327
Reputation: 2034
Firstly, please check this example for a working sample of what you are trying to accomplish.
There are a few issues here,
wx.EVT_CLOSE
and handle that closing event properly.wx.NO_BORDER
on top of the default style. Otherwise, your window won't minimize at all.on_exit
of tray icon, you should signal the main frame to be closed by wx.CallAfter(self.frame.Close)
See the below code for an application of above tips:
class MyFrame(wx.Frame):
def __init__(self, parent, title):
wx.Frame.__init__(self, parent, title=title, size=(windowWidth,windowHeight), style=wx.DEFAULT_FRAME_STYLE | wx.NO_BORDER) # Frame without borders
self.tbicon = TaskBarIcon(self)
self.Bind(wx.EVT_CLOSE, self.OnCloseWindow)
def OnCloseWindow(self, evt):
self.tbicon.RemoveIcon()
self.tbicon.Destroy()
self.Destroy()
wx.GetApp().ExitMainLoop()
evt.Skip()
The modifications for TaskBarIcon
:
class TaskBarIcon(wx.TaskBarIcon):
def on_left_down(self, event):
print('on_left_down of tray icon')
if self.frame.IsIconized():
self.frame.Iconize(False)
if not self.frame.IsShown():
self.frame.Show(True)
self.frame.Raise()
def openPrefsFromMenu(self, event):
print('open prefs from menu')
def on_exit(self, event):
wx.CallAfter(self.frame.Close)
Upvotes: 2