moses-palmer / pystray

GNU General Public License v3.0
482 stars 59 forks source link

sys.exit(0) raises exception #120

Closed ReenigneArcher closed 2 years ago

ReenigneArcher commented 2 years ago

Hello, I am having a problem attempting to have a menu item that quits my program (a Flask application) using sys.exit(0).

I have attempted to simplify the code here:

# standard imports
import os
import sys

# lib imports
import pystray
from PIL import Image
from pystray import MenuItem

def tray_initialize():
    image = Image.open('my_icon.ico')

    menu = (
        MenuItem(text='Restart', action=tray_restart),
        MenuItem(text='Quit', action=tray_quit),
    )

    tray_icon = pystray.Icon("retroarcher", image, definitions.Names().name, menu=menu)

    return tray_icon

def tray_end():
    tray_hide()
    tray_stop()

def tray_hide():
    icon.visible = False

def tray_stop():
    icon.stop()

def tray_quit():
    tray_end()
    sys.exit(0)

def tray_restart():
    tray_end()
    os.execv(sys.executable, ['python'] + sys.argv)

def tray_run():
    icon.run_detached()  # todo - this is blocking ctrl-c from terminating

icon = tray_initialize()
tray_run()

When clicking "Quit" in the system tray menu, I get the following traceback (note that line numbers and modules are different than the code above):

Traceback (most recent call last):
  File "C:\Users\ReenigneArcher\Documents\GitHub\RetroArcher\RetroArcher\venv\lib\site-packages\pystray\_win32.py", line 401, in _dispatcher
    return int(icon._message_handlers.get(
  File "C:\Users\ReenigneArcher\Documents\GitHub\RetroArcher\RetroArcher\venv\lib\site-packages\pystray\_win32.py", line 213, in _on_notify
    descriptors[index - 1](self)
  File "C:\Users\ReenigneArcher\Documents\GitHub\RetroArcher\RetroArcher\venv\lib\site-packages\pystray\_base.py", line 324, in inner
    callback(self)
  File "C:\Users\ReenigneArcher\Documents\GitHub\RetroArcher\RetroArcher\venv\lib\site-packages\pystray\_base.py", line 449, in __call__
    return self._action(icon, self)
  File "C:\Users\ReenigneArcher\Documents\GitHub\RetroArcher\RetroArcher\venv\lib\site-packages\pystray\_base.py", line 544, in wrapper0
    return action()
  File "C:\Users\ReenigneArcher\Documents\GitHub\RetroArcher\RetroArcher\pyra\tray_icon.py", line 65, in tray_quit
    pyra.stop()
  File "C:\Users\ReenigneArcher\Documents\GitHub\RetroArcher\RetroArcher\pyra\__init__.py", line 98, in stop
    sys.exit(exit_code)
SystemExit: 0

Do you have any suggestions for how to gracefully exit from a system tray menu command?

moses-palmer commented 2 years ago

Thank you for your report.

How to gracefully stop your application really depends on other libraries and frameworks used in your application, so I cannot give a generic answer.

I notice, however, that you call run_detached, so pystray is not in charge of your main loop. Perhaps Flask is? In that case, graceful shutdown would simply be to terminate your Flask application in tray_quit. You would have to consult the documentation on how to do this.