Collection of tools useful for audio production
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

670 lines
23KB

  1. #!/usr/bin/env python3
  2. # -*- coding: utf-8 -*-
  3. # KDE, App-Indicator or Qt Systray
  4. # Copyright (C) 2011-2012 Filipe Coelho <falktx@falktx.com>
  5. #
  6. # This program is free software; you can redistribute it and/or modify
  7. # it under the terms of the GNU General Public License as published by
  8. # the Free Software Foundation; either version 2 of the License, or
  9. # any later version.
  10. #
  11. # This program is distributed in the hope that it will be useful,
  12. # but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. # GNU General Public License for more details.
  15. #
  16. # For a full copy of the GNU General Public License see the COPYING file
  17. # Imports (Global)
  18. import os, sys
  19. from PyQt4.QtCore import QTimer, SIGNAL
  20. from PyQt4.QtGui import QAction, QIcon, QMenu, QSystemTrayIcon
  21. try:
  22. if os.getenv("DESKTOP_SESSION") in ("ubuntu", "ubuntu-2d") and not os.path.exists("/var/cadence/no_app_indicators"):
  23. # Check current Qt theme. If Gtk+, use Gtk2 AppIndicator
  24. style = None
  25. if len(sys.argv) > 2 and "-style" in sys.argv:
  26. i = sys.argv.index("-style")
  27. if i < len(sys.argv):
  28. style = sys.argv[i+1]
  29. check_cmd = "python3 -c 'import sys; from PyQt4.QtGui import QApplication; app = QApplication(sys.argv); print(app.style().objectName())'"
  30. if style:
  31. check_cmd += " -style %s" % style
  32. from subprocess import getoutput
  33. needsGtk2 = bool(getoutput(check_cmd).strip().lower() in ("gtk", "gtk+"))
  34. if needsGtk2:
  35. from gi import pygtkcompat
  36. pygtkcompat.enable()
  37. pygtkcompat.enable_gtk(version="2.0")
  38. from gi.repository import Gtk, AppIndicator
  39. else:
  40. from gi.repository import Gtk, AppIndicator3 as AppIndicator
  41. TrayEngine = "AppIndicator"
  42. elif os.getenv("KDE_FULL_SESSION") or os.getenv("DESKTOP_SESSION") == "kde-plasma":
  43. from PyKDE4.kdeui import KAction, KIcon, KMenu, KStatusNotifierItem
  44. TrayEngine = "KDE"
  45. else:
  46. TrayEngine = "Qt"
  47. except:
  48. TrayEngine = "Qt"
  49. print("Using Tray Engine '%s'" % TrayEngine)
  50. iActNameId = 0
  51. iActWidget = 1
  52. iActParentMenuId = 2
  53. iActFunc = 3
  54. iSepNameId = 0
  55. iSepWidget = 1
  56. iSepParentMenuId = 2
  57. iMenuNameId = 0
  58. iMenuWidget = 1
  59. iMenuParentMenuId = 2
  60. # Get Icon from user theme, using our own as backup (Oxygen)
  61. def getIcon(icon, size=16):
  62. return QIcon.fromTheme(icon, QIcon(":/%ix%i/%s.png" % (size, size, icon)))
  63. # Global Systray class
  64. class GlobalSysTray(object):
  65. def __init__(self, parent, name, icon):
  66. object.__init__(self)
  67. self._parent = parent
  68. self._gtk_running = False
  69. self._quit_added = False
  70. self.act_indexes = []
  71. self.sep_indexes = []
  72. self.menu_indexes = []
  73. if TrayEngine == "KDE":
  74. self.menu = KMenu(parent)
  75. self.menu.setTitle(name)
  76. self.tray = KStatusNotifierItem()
  77. self.tray.setAssociatedWidget(parent)
  78. self.tray.setCategory(KStatusNotifierItem.ApplicationStatus)
  79. self.tray.setContextMenu(self.menu)
  80. self.tray.setIconByPixmap(getIcon(icon))
  81. self.tray.setTitle(name)
  82. self.tray.setToolTipTitle(" ")
  83. self.tray.setToolTipIconByPixmap(getIcon(icon))
  84. # Double-click is managed by KDE
  85. elif TrayEngine == "AppIndicator":
  86. self.menu = Gtk.Menu()
  87. self.tray = AppIndicator.Indicator.new(name, icon, AppIndicator.IndicatorCategory.APPLICATION_STATUS)
  88. self.tray.set_menu(self.menu)
  89. # Double-click is not possible with App-Indicators
  90. elif TrayEngine == "Qt":
  91. self.menu = QMenu(parent)
  92. self.tray = QSystemTrayIcon(getIcon(icon))
  93. self.tray.setContextMenu(self.menu)
  94. self.tray.setParent(parent)
  95. self.tray.connect(self.tray, SIGNAL("activated(QSystemTrayIcon::ActivationReason)"), self.qt_systray_clicked)
  96. # -------------------------------------------------------------------------------------------
  97. def addAction(self, act_name_id, act_name_string, is_check=False):
  98. if TrayEngine == "KDE":
  99. act_widget = KAction(act_name_string, self.menu)
  100. act_widget.setCheckable(is_check)
  101. self.menu.addAction(act_widget)
  102. elif TrayEngine == "AppIndicator":
  103. if is_check:
  104. act_widget = Gtk.CheckMenuItem(act_name_string)
  105. else:
  106. act_widget = Gtk.ImageMenuItem(act_name_string)
  107. act_widget.set_image(None)
  108. act_widget.show()
  109. self.menu.append(act_widget)
  110. elif TrayEngine == "Qt":
  111. act_widget = QAction(act_name_string, self.menu)
  112. act_widget.setCheckable(is_check)
  113. self.menu.addAction(act_widget)
  114. else:
  115. act_widget = None
  116. act_obj = [None, None, None, None]
  117. act_obj[iActNameId] = act_name_id
  118. act_obj[iActWidget] = act_widget
  119. self.act_indexes.append(act_obj)
  120. def addSeparator(self, sep_name_id):
  121. if TrayEngine == "KDE":
  122. sep_widget = self.menu.addSeparator()
  123. elif TrayEngine == "AppIndicator":
  124. sep_widget = Gtk.SeparatorMenuItem()
  125. sep_widget.show()
  126. self.menu.append(sep_widget)
  127. elif TrayEngine == "Qt":
  128. sep_widget = self.menu.addSeparator()
  129. else:
  130. sep_widget = None
  131. sep_obj = [None, None, None]
  132. sep_obj[iSepNameId] = sep_name_id
  133. sep_obj[iSepWidget] = sep_widget
  134. self.sep_indexes.append(sep_obj)
  135. def addMenu(self, menu_name_id, menu_name_string):
  136. if TrayEngine == "KDE":
  137. menu_widget = KMenu(menu_name_string, self.menu)
  138. self.menu.addMenu(menu_widget)
  139. elif TrayEngine == "AppIndicator":
  140. menu_widget = Gtk.MenuItem(menu_name_string)
  141. menu_parent = Gtk.Menu()
  142. menu_widget.set_submenu(menu_parent)
  143. menu_widget.show()
  144. self.menu.append(menu_widget)
  145. elif TrayEngine == "Qt":
  146. menu_widget = QMenu(menu_name_string, self.menu)
  147. self.menu.addMenu(menu_widget)
  148. else:
  149. menu_widget = None
  150. menu_obj = [None, None, None]
  151. menu_obj[iMenuNameId] = menu_name_id
  152. menu_obj[iMenuWidget] = menu_widget
  153. self.menu_indexes.append(menu_obj)
  154. # -------------------------------------------------------------------------------------------
  155. def addMenuAction(self, menu_name_id, act_name_id, act_name_string, is_check=False):
  156. i = self.get_menu_index(menu_name_id)
  157. if i < 0: return
  158. menu_widget = self.menu_indexes[i][iMenuWidget]
  159. if TrayEngine == "KDE":
  160. act_widget = KAction(act_name_string, menu_widget)
  161. act_widget.setCheckable(is_check)
  162. menu_widget.addAction(act_widget)
  163. elif TrayEngine == "AppIndicator":
  164. menu_widget = menu_widget.get_submenu()
  165. if is_check:
  166. act_widget = Gtk.CheckMenuItem(act_name_string)
  167. else:
  168. act_widget = Gtk.ImageMenuItem(act_name_string)
  169. act_widget.set_image(None)
  170. act_widget.show()
  171. menu_widget.append(act_widget)
  172. elif TrayEngine == "Qt":
  173. act_widget = QAction(act_name_string, menu_widget)
  174. act_widget.setCheckable(is_check)
  175. menu_widget.addAction(act_widget)
  176. else:
  177. act_widget = None
  178. act_obj = [None, None, None, None]
  179. act_obj[iActNameId] = act_name_id
  180. act_obj[iActWidget] = act_widget
  181. act_obj[iActParentMenuId] = menu_name_id
  182. self.act_indexes.append(act_obj)
  183. def addMenuSeparator(self, menu_name_id, sep_name_id):
  184. i = self.get_menu_index(menu_name_id)
  185. if i < 0: return
  186. menu_widget = self.menu_indexes[i][iMenuWidget]
  187. if TrayEngine == "KDE":
  188. sep_widget = menu_widget.addSeparator()
  189. elif TrayEngine == "AppIndicator":
  190. menu_widget = menu_widget.get_submenu()
  191. sep_widget = Gtk.SeparatorMenuItem()
  192. sep_widget.show()
  193. menu_widget.append(sep_widget)
  194. elif TrayEngine == "Qt":
  195. sep_widget = menu_widget.addSeparator()
  196. else:
  197. sep_widget = None
  198. sep_obj = [None, None, None]
  199. sep_obj[iSepNameId] = sep_name_id
  200. sep_obj[iSepWidget] = sep_widget
  201. sep_obj[iSepParentMenuId] = menu_name_id
  202. self.sep_indexes.append(sep_obj)
  203. #def addSubMenu(self, menu_name_id, new_menu_name_id, new_menu_name_string):
  204. #menu_index = self.get_menu_index(menu_name_id)
  205. #if menu_index < 0: return
  206. #menu_widget = self.menu_indexes[menu_index][1]
  207. ##if TrayEngine == "KDE":
  208. ##new_menu_widget = KMenu(new_menu_name_string, self.menu)
  209. ##menu_widget.addMenu(new_menu_widget)
  210. ##elif TrayEngine == "AppIndicator":
  211. ##new_menu_widget = Gtk.MenuItem(new_menu_name_string)
  212. ##new_menu_widget.show()
  213. ##menu_widget.get_submenu().append(new_menu_widget)
  214. ##parent_menu_widget = Gtk.Menu()
  215. ##new_menu_widget.set_submenu(parent_menu_widget)
  216. ##else:
  217. #if (1):
  218. #new_menu_widget = QMenu(new_menu_name_string, self.menu)
  219. #menu_widget.addMenu(new_menu_widget)
  220. #self.menu_indexes.append([new_menu_name_id, new_menu_widget, menu_name_id])
  221. # -------------------------------------------------------------------------------------------
  222. def connect(self, act_name_id, act_func):
  223. i = self.get_act_index(act_name_id)
  224. if i < 0: return
  225. act_widget = self.act_indexes[i][iActWidget]
  226. if TrayEngine == "KDE":
  227. self.tray.connect(act_widget, SIGNAL("triggered()"), act_func)
  228. elif TrayEngine == "AppIndicator":
  229. act_widget.connect("activate", self.gtk_call_func, act_name_id)
  230. elif TrayEngine == "Qt":
  231. self.tray.connect(act_widget, SIGNAL("triggered()"), act_func)
  232. self.act_indexes[i][iActFunc] = act_func
  233. # -------------------------------------------------------------------------------------------
  234. #def setActionChecked(self, act_name_id, yesno):
  235. #index = self.get_act_index(act_name_id)
  236. #if index < 0: return
  237. #act_widget = self.act_indexes[index][1]
  238. ##if TrayEngine == "KDE":
  239. ##act_widget.setChecked(yesno)
  240. ##elif TrayEngine == "AppIndicator":
  241. ##if type(act_widget) != Gtk.CheckMenuItem:
  242. ##return # Cannot continue
  243. ##act_widget.set_active(yesno)
  244. ##else:
  245. #if (1):
  246. #act_widget.setChecked(yesno)
  247. def setActionEnabled(self, act_name_id, yesno):
  248. i = self.get_act_index(act_name_id)
  249. if i < 0: return
  250. act_widget = self.act_indexes[i][iActWidget]
  251. if TrayEngine == "KDE":
  252. act_widget.setEnabled(yesno)
  253. elif TrayEngine == "AppIndicator":
  254. act_widget.set_sensitive(yesno)
  255. elif TrayEngine == "Qt":
  256. act_widget.setEnabled(yesno)
  257. def setActionIcon(self, act_name_id, icon):
  258. i = self.get_act_index(act_name_id)
  259. if i < 0: return
  260. act_widget = self.act_indexes[i][iActWidget]
  261. if TrayEngine == "KDE":
  262. act_widget.setIcon(KIcon(icon))
  263. elif TrayEngine == "AppIndicator":
  264. if not isinstance(act_widget, Gtk.ImageMenuItem):
  265. # Cannot use icons here
  266. return
  267. act_widget.set_image(Gtk.Image.new_from_icon_name(icon, Gtk.IconSize.MENU))
  268. #act_widget.set_always_show_image(True)
  269. elif TrayEngine == "Qt":
  270. act_widget.setIcon(getIcon(icon))
  271. def setActionText(self, act_name_id, text):
  272. i = self.get_act_index(act_name_id)
  273. if i < 0: return
  274. act_widget = self.act_indexes[i][iActWidget]
  275. if TrayEngine == "KDE":
  276. act_widget.setText(text)
  277. elif TrayEngine == "AppIndicator":
  278. if isinstance(act_widget, Gtk.ImageMenuItem):
  279. # Fix icon reset
  280. last_icon = act_widget.get_image()
  281. act_widget.set_label(text)
  282. act_widget.set_image(last_icon)
  283. else:
  284. act_widget.set_label(text)
  285. elif TrayEngine == "Qt":
  286. act_widget.setText(text)
  287. def setIcon(self, icon):
  288. if TrayEngine == "KDE":
  289. self.tray.setIconByPixmap(getIcon(icon))
  290. #self.tray.setToolTipIconByPixmap(getIcon(icon))
  291. elif TrayEngine == "AppIndicator":
  292. self.tray.set_icon(icon)
  293. elif TrayEngine == "Qt":
  294. self.tray.setIcon(getIcon(icon))
  295. def setToolTip(self, text):
  296. if TrayEngine == "KDE":
  297. self.tray.setToolTipSubTitle(text)
  298. elif TrayEngine == "AppIndicator":
  299. # ToolTips are disabled in App-Indicators by design
  300. pass
  301. elif TrayEngine == "Qt":
  302. self.tray.setToolTip(text)
  303. # -------------------------------------------------------------------------------------------
  304. #def removeAction(self, act_name_id):
  305. #index = self.get_act_index(act_name_id)
  306. #if index < 0: return
  307. #act_widget = self.act_indexes[index][1]
  308. #parent_menu_widget = self.get_parent_menu_widget(self.act_indexes[index][2])
  309. ##if TrayEngine == "KDE":
  310. ##parent_menu_widget.removeAction(act_widget)
  311. ##elif TrayEngine == "AppIndicator":
  312. ##act_widget.hide()
  313. ##parent_menu_widget.remove(act_widget)
  314. ##else:
  315. #if (1):
  316. #parent_menu_widget.removeAction(act_widget)
  317. #self.act_indexes.pop(index)
  318. #def removeSeparator(self, sep_name_id):
  319. #index = self.get_sep_index(sep_name_id)
  320. #if index < 0: return
  321. #sep_widget = self.sep_indexes[index][1]
  322. #parent_menu_widget = self.get_parent_menu_widget(self.sep_indexes[index][2])
  323. ##if TrayEngine == "KDE":
  324. ##parent_menu_widget.removeAction(sep_widget)
  325. ##elif TrayEngine == "AppIndicator":
  326. ##sep_widget.hide()
  327. ##parent_menu_widget.remove(sep_widget)
  328. ##else:
  329. #if (1):
  330. #parent_menu_widget.removeAction(sep_widget)
  331. #self.sep_indexes.pop(index)
  332. #def removeMenu(self, menu_name_id):
  333. #index = self.get_menu_index(menu_name_id)
  334. #if index < 0: return
  335. #menu_widget = self.menu_indexes[index][1]
  336. #parent_menu_widget = self.get_parent_menu_widget(self.menu_indexes[index][2])
  337. ##if TrayEngine == "KDE":
  338. ##parent_menu_widget.removeAction(menu_widget.menuAction())
  339. ##elif TrayEngine == "AppIndicator":
  340. ##menu_widget.hide()
  341. ##parent_menu_widget.remove(menu_widget.get_submenu())
  342. ##else:
  343. #if (1):
  344. #parent_menu_widget.removeAction(menu_widget.menuAction())
  345. #self.remove_actions_by_menu_name_id(menu_name_id)
  346. #self.remove_separators_by_menu_name_id(menu_name_id)
  347. #self.remove_submenus_by_menu_name_id(menu_name_id)
  348. # -------------------------------------------------------------------------------------------
  349. #def clearAll(self):
  350. ##if TrayEngine == "KDE":
  351. ##self.menu.clear()
  352. ##elif TrayEngine == "AppIndicator":
  353. ##for child in self.menu.get_children():
  354. ##self.menu.remove(child)
  355. ##else:
  356. #if (1):
  357. #self.menu.clear()
  358. #self.act_indexes = []
  359. #self.sep_indexes = []
  360. #self.menu_indexes = []
  361. #def clearMenu(self, menu_name_id):
  362. #menu_index = self.get_menu_index(menu_name_id)
  363. #if menu_index < 0: return
  364. #menu_widget = self.menu_indexes[menu_index][1]
  365. ##if TrayEngine == "KDE":
  366. ##menu_widget.clear()
  367. ##elif TrayEngine == "AppIndicator":
  368. ##for child in menu_widget.get_submenu().get_children():
  369. ##menu_widget.get_submenu().remove(child)
  370. ##else:
  371. #if (1):
  372. #menu_widget.clear()
  373. #list_of_submenus = [menu_name_id]
  374. #for x in range(0, 10): # 10x level deep, should cover all cases...
  375. #for this_menu_name_id, menu_widget, parent_menu_id in self.menu_indexes:
  376. #if parent_menu_id in list_of_submenus and this_menu_name_id not in list_of_submenus:
  377. #list_of_submenus.append(this_menu_name_id)
  378. #for this_menu_name_id in list_of_submenus:
  379. #self.remove_actions_by_menu_name_id(this_menu_name_id)
  380. #self.remove_separators_by_menu_name_id(this_menu_name_id)
  381. #self.remove_submenus_by_menu_name_id(this_menu_name_id)
  382. # -------------------------------------------------------------------------------------------
  383. def getTrayEngine(self):
  384. return TrayEngine
  385. def isTrayAvailable(self):
  386. if TrayEngine in ("KDE", "Qt"):
  387. return QSystemTrayIcon.isSystemTrayAvailable()
  388. elif TrayEngine == "AppIndicator":
  389. # Ubuntu/Unity always has a systray
  390. return True
  391. else:
  392. return False
  393. # -------------------------------------------------------------------------------------------
  394. def show(self):
  395. if not self._quit_added:
  396. self._quit_added = True
  397. if TrayEngine != "KDE":
  398. self.addSeparator("_quit")
  399. self.addAction("show", self._parent.tr("Minimize"))
  400. self.addAction("quit", self._parent.tr("Quit"))
  401. self.setActionIcon("quit", "application-exit")
  402. self.connect("show", self.__hideShowCall)
  403. self.connect("quit", self.__quitCall)
  404. if TrayEngine == "KDE":
  405. self.tray.setStatus(KStatusNotifierItem.Active)
  406. elif TrayEngine == "AppIndicator":
  407. self.tray.set_status(AppIndicator.IndicatorStatus.ACTIVE)
  408. elif TrayEngine == "Qt":
  409. self.tray.show()
  410. def hide(self):
  411. if TrayEngine == "KDE":
  412. self.tray.setStatus(KStatusNotifierItem.Passive)
  413. elif TrayEngine == "AppIndicator":
  414. self.tray.set_status(AppIndicator.IndicatorStatus.PASSIVE)
  415. elif TrayEngine == "Qt":
  416. self.tray.hide()
  417. def close(self):
  418. if TrayEngine == "KDE":
  419. self.menu.close()
  420. elif TrayEngine == "AppIndicator":
  421. if self._gtk_running:
  422. self._gtk_running = False
  423. Gtk.main_quit()
  424. elif TrayEngine == "Qt":
  425. self.menu.close()
  426. def exec_(self, app):
  427. if TrayEngine == "AppIndicator":
  428. self._gtk_running = True
  429. return Gtk.main()
  430. else:
  431. return app.exec_()
  432. # -------------------------------------------------------------------------------------------
  433. def get_act_index(self, act_name_id):
  434. for i in range(len(self.act_indexes)):
  435. if self.act_indexes[i][iActNameId] == act_name_id:
  436. return i
  437. else:
  438. print("systray.py - Failed to get action index for %s" % act_name_id)
  439. return -1
  440. def get_sep_index(self, sep_name_id):
  441. for i in range(len(self.sep_indexes)):
  442. if self.sep_indexes[i][iSepNameId] == sep_name_id:
  443. return i
  444. else:
  445. print("systray.py - Failed to get separator index for %s" % sep_name_id)
  446. return -1
  447. def get_menu_index(self, menu_name_id):
  448. for i in range(len(self.menu_indexes)):
  449. if self.menu_indexes[i][iMenuNameId] == menu_name_id:
  450. return i
  451. else:
  452. print("systray.py - Failed to get menu index for %s" % menu_name_id)
  453. return -1
  454. #def get_parent_menu_widget(self, parent_menu_id):
  455. #if parent_menu_id != None:
  456. #menu_index = self.get_menu_index(parent_menu_id)
  457. #if menu_index >= 0:
  458. #return self.menu_indexes[menu_index][1]
  459. #else:
  460. #print("systray.py::Failed to get parent Menu widget for", parent_menu_id)
  461. #return None
  462. #else:
  463. #return self.menu
  464. #def remove_actions_by_menu_name_id(self, menu_name_id):
  465. #h = 0
  466. #for i in range(len(self.act_indexes)):
  467. #act_name_id, act_widget, parent_menu_id, act_func = self.act_indexes[i - h]
  468. #if parent_menu_id == menu_name_id:
  469. #self.act_indexes.pop(i - h)
  470. #h += 1
  471. #def remove_separators_by_menu_name_id(self, menu_name_id):
  472. #h = 0
  473. #for i in range(len(self.sep_indexes)):
  474. #sep_name_id, sep_widget, parent_menu_id = self.sep_indexes[i - h]
  475. #if parent_menu_id == menu_name_id:
  476. #self.sep_indexes.pop(i - h)
  477. #h += 1
  478. #def remove_submenus_by_menu_name_id(self, submenu_name_id):
  479. #h = 0
  480. #for i in range(len(self.menu_indexes)):
  481. #menu_name_id, menu_widget, parent_menu_id = self.menu_indexes[i - h]
  482. #if parent_menu_id == submenu_name_id:
  483. #self.menu_indexes.pop(i - h)
  484. #h += 1
  485. # -------------------------------------------------------------------------------------------
  486. def gtk_call_func(self, gtkmenu, act_name_id):
  487. i = self.get_act_index(act_name_id)
  488. if i < 0: return None
  489. return self.act_indexes[i][iActFunc]
  490. def qt_systray_clicked(self, reason):
  491. if reason in (QSystemTrayIcon.DoubleClick, QSystemTrayIcon.Trigger):
  492. self.__hideShowCall()
  493. # -------------------------------------------------------------------------------------------
  494. def __hideShowCall(self):
  495. if self._parent.isVisible():
  496. self.setActionText("show", self._parent.tr("Restore"))
  497. self._parent.hide()
  498. else:
  499. self.setActionText("show", self._parent.tr("Minimize"))
  500. if self._parent.isMaximized():
  501. self._parent.showMaximized()
  502. else:
  503. self._parent.showNormal()
  504. QTimer.singleShot(100, self.__raiseWindow)
  505. def __quitCall(self):
  506. self._parent.close()
  507. def __raiseWindow(self):
  508. self._parent.activateWindow()
  509. self._parent.raise_()
  510. #--------------- main ------------------
  511. if __name__ == '__main__':
  512. from PyQt4.QtGui import QApplication, QDialog, QMessageBox
  513. class ExampleGUI(QDialog):
  514. def __init__(self, parent=None):
  515. QDialog.__init__(self, parent)
  516. self.setWindowIcon(getIcon("audacity"))
  517. self.systray = GlobalSysTray(self, "Claudia", "claudia")
  518. self.systray.addAction("about", self.tr("About"))
  519. self.systray.setIcon("audacity")
  520. self.systray.setToolTip("Demo systray app")
  521. self.systray.connect("about", self.about)
  522. self.systray.show()
  523. def about(self):
  524. QMessageBox.about(self, self.tr("About"), self.tr("Systray Demo"))
  525. def done(self, r):
  526. QDialog.done(self, r)
  527. self.close()
  528. def closeEvent(self, event):
  529. self.systray.close()
  530. QDialog.closeEvent(self, event)
  531. app = QApplication(sys.argv)
  532. gui = ExampleGUI()
  533. gui.show()
  534. sys.exit(gui.systray.exec_(app))