2

I've written a program using tkinter which when the main window is closed is supposed to be minimized to the system tray. But when I try to exit the program clicking "Close" in the tray that triggers the following function:

def quit_window(icon, item):
    icon.stop() # Удаление иконки из трея
    sys.exit(0) # Завершение программы

But it does not work and throws the following exception:

An error occurred when calling message handler
Traceback (most recent call last):
  File "C:\Users\a-par\mini_library_2020\env\lib\site-packages\pystray\_win32.py", line 386, in _dispatcher
    return int(icon._message_handlers.get(
  File "C:\Users\a-par\mini_library_2020\env\lib\site-packages\pystray\_win32.py", line 207, in _on_notify 
    descriptors[index - 1](self)
  File "C:\Users\a-par\mini_library_2020\env\lib\site-packages\pystray\_base.py", line 267, in inner
    callback(self)
  File "C:\Users\a-par\mini_library_2020\env\lib\site-packages\pystray\_base.py", line 368, in __call__
    return self._action(icon, self)
  File "c:/Users/a-par/mini_library_2020/LC.pyw", line 2976, in quit_window
    sys.exit(0)
SystemExit: 0

Also there's a VK bot in the program which is supposed to work when the program is minimized (it's the reason for actually minimizing to the tray). The bot works in a different from GUI thread. I tried to delete the bot fully but it didn't any help. Maybe the problem is threads but I don't think that way...

Minimally reproducible non-working code:

import pystray
import sys
import time
from PIL import Image
from pystray import Menu, MenuItem


def exit_action(icon):
    sys.exit(0)


def setup(icon):
    icon.visible = True
    
    i = 0
    while icon.visible:
        # Some payload code
        print(i)
        i += 1
        
        time.sleep(5)


def init_icon():
    icon = pystray.Icon('mon')
    icon.menu = Menu(
        MenuItem('Exit', lambda : exit_action(icon)),
    )
    icon.icon = Image.open('C:/Users/a-par/mini_library_2020/logo.ico')
    icon.title = 'tooltip'

    icon.run(setup)

init_icon()

Video

6
  • Well instead of sys.exit(0), I use exit(). To read more about the difference read this. Also the error is just telling you that that function wants to close the program. Nothing more Commented Apr 7, 2021 at 14:00
  • @TheLizzard, I understand, but it doesn't let you close the program. Because of this, the function does not work as it should. Also, when exit() displays an error, but instead of 0, the value is None Commented Apr 7, 2021 at 14:11
  • I think you should ignore the error because technically each time you close any python program it raises an error and that is how it closes. Commented Apr 7, 2021 at 14:14
  • I would be happy, but only she continues to hang between two "worlds" and loads the system Commented Apr 7, 2021 at 14:22
  • I am not that familiar with how pystray works but can you just set a global variable and when the variable is True you call exit() outside of that function? If that doesn't work I am, out of ideas Commented Apr 7, 2021 at 14:27

1 Answer 1

2

sys.exit() will not work as it is not executed from the main thread or something. You need to use icon.stop() to close the event loop of pystray, thereby stopping the entire program.

Sign up to request clarification or add additional context in comments.

1 Comment

icon.stop() doesn't works when setup parameter is provided to the 'run' method.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.