我是python和wxPython的新手,目前正在开发一个小型(仅限linux的目标)脚本,其中包含一个托盘图标(任务栏图标)和一个主窗口(Frame)。
我现在意识到一个问题,我不知道如何处理。
我试着尽量减少这篇文章的代码,希望它有所帮助。
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()
答案 0 :(得分:2)
首先,请查看this example,了解您要完成的工作样本。
这里有一些问题,
wx.EVT_CLOSE
并正确处理该结束活动。wx.NO_BORDER
。否则,您的窗口根本不会最小化。on_exit
范围内,您应通过wx.CallAfter(self.frame.Close)
有关上述提示的应用,请参阅以下代码:
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()
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)