-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathtray_icon.py
140 lines (98 loc) · 3.77 KB
/
tray_icon.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
# TRAY ICON IMPLEMENTATION (https://stackoverflow.com/a/48401917/14113019)
# <<< IMPORTS AND CONFIGURATION >>>
import wx
import wx.adv
from threading import Thread
wx.DisableAsserts() # to disable wxWidgets Debug Alert due to application exit initiating from another thread
def create_menu_item(menu, label, func):
"""
Creates a menu item with the specified label and binds it to the given function.
:param menu: The menu to which the item will be added.
:param label: The label text of the menu item.
:param func: The function to be called when the menu item is selected.
:return: The created menu item.
"""
item = wx.MenuItem(menu, -1, label)
menu.Bind(wx.EVT_MENU, func, id=item.GetId())
menu.Append(item)
return item
class _TrayIcon(wx.adv.TaskBarIcon):
def __init__(self, name: str, icon: str, menus: tuple, left_click_action, include_quit):
super(_TrayIcon, self).__init__()
self.name = name
self.menus = menus
self.left_click_action = left_click_action
self.include_quit = include_quit
self.set_icon(icon)
self.Bind(wx.adv.EVT_TASKBAR_LEFT_DOWN, self.on_left_down)
def CreatePopupMenu(self):
"""
Creates and returns the context menu for the tray icon.
:return: The created wx.Menu.
"""
menu = wx.Menu()
for index, menu_data in enumerate(self.menus):
create_menu_item(menu, menu_data["name"], menu_data["action"])
if index != len(self.menus) - 1:
menu.AppendSeparator()
if self.include_quit:
if len(self.menus) != 0:
menu.AppendSeparator()
create_menu_item(menu, "Quit", self.on_exit)
return menu
def set_icon(self, path):
"""
Sets the icon image for the tray icon.
:param path: The path to the icon image file.
"""
icon = wx.Icon(path)
self.SetIcon(icon, self.name)
def on_left_down(self, event): # NOQA
"""
Handles left-click events on the tray icon.
:param event: The wx.EVT_TASKBAR_LEFT_DOWN event.
"""
if self.left_click_action is None:
return
self.left_click_action()
def on_exit(self, event): # NOQA
"""
Handles the 'Quit' menu item.
:param event: The wx.EVT_MENU event.
"""
wx.CallAfter(self.Destroy)
class _TrayIconApp(wx.App):
def __init__(self, name: str, icon: str, menus: tuple, left_click_action, include_quit):
self.name = name
self.icon = icon
self.menus = menus
self.left_click_action = left_click_action
self.include_quit = include_quit
super().__init__()
def OnInit(self):
"""
Initializes the wxPython application.
:return: True to indicate a successful initialization.
"""
_TrayIcon(self.name, self.icon, self.menus, self.left_click_action, self.include_quit)
return True
class TrayIconApp:
def __init__(self, name: str, icon: str, menus: tuple, left_click_action=None, include_quit=False):
self.name = name
self.icon = icon
self.menus = menus
self.left_click_action = left_click_action
self.include_quit = include_quit
self.app = None
def run(self):
"""
Runs the tray icon application.
"""
self.app = _TrayIconApp(self.name, self.icon, self.menus, self.left_click_action, self.include_quit)
self.app.MainLoop()
def run_detached(self, daemon=False):
"""
Runs the tray icon application in a separate thread.
:param daemon: Whether the thread should be a daemon thread (optional).
"""
Thread(target=self.run, daemon=daemon).start()