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.

689 lines
23KB

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