Reputation: 195
I'm trying to use pystray without blocking the main thread. Based on the pystray docs we can use the function run_detached()
to start without blocking.
I'm using pystray on windows so, apparently I don't need to pass any argument to run_detached()
to work.
The first thing I tried is to run this code:
import pystray
from pystray import MenuItem as item
from PIL import Image, ImageTk
def show_window(icon):
print('Test')
def quit_window(icon):
icon.stop()
icon = 'icon.ico'
image=Image.open(icon)
menu=pystray.Menu(item('Show', show_window, default=True), item('Quit', quit_window))
icon=pystray.Icon("name", image, "My System Tray Icon", menu)
icon.run_detached()
But I received this error:
Exception in thread Thread-2:
Traceback (most recent call last):
File "...\lib\threading.py", line 973, in _bootstrap_inner
self.run()
File "...\lib\threading.py", line 910, in run
self._target(*self._args, **self._kwargs)
File "...\lib\site-packages\pystray\_base.py", line 384, in <lambda>
threading.Thread(target=lambda: self.run(setup)).start()
NameError: name 'setup' is not defined
So I tried to bypass this error by changing the line 384 in _base.py removing the setup variable
#threading.Thread(target=lambda: self.run(setup)).start()
threading.Thread(target=lambda: self.run()).start()
The code worked like expected and created the tray icon with the menu buttons working properly.
The problem is when I press "Quit" because the stop()
function is not working like when I use icon.run()
.
The thread appears to keep running and the tray icon stay frozen and the program don't end.
Is there another way to make this work properly?
EDIT: I found this issue in the official git repository LINK and it appears to be a bug already reported. I want to know if is possible to make a workaround.
Upvotes: 2
Views: 2931
Reputation: 1
Based on https://github.com/moses-palmer/pystray/issues/94 I found changing
threading.Thread(target=lambda: self.run()).start()
into
threading.Thread(deamon=true,target=lambda: self.run()).start()
works for me. My icon.stop() actually closes the thread now
Upvotes: 0
Reputation: 1
Modifying the stop() function further to exit from the thread using os._exit will work if you don't need the calling thread to remain available.
Upvotes: 0