【问题标题】:Why can't I close when using pystray?为什么我在使用 pystray 时无法关闭?
【发布时间】:2021-04-07 13:53:17
【问题描述】:

我使用 tkinter 编写了一个程序,当主窗口关闭时,它应该被最小化到系统托盘。但是当我尝试退出程序时,单击托盘中的“关闭”会触发以下功能:

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

但它不起作用并抛出以下异常:

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

程序中还有一个 VK bot,它应该在程序最小化时工作(这是实际最小化到托盘的原因)。该机器人在不同于 GUI 线程中工作。我试图完全删除该机器人,但没有任何帮助。也许问题是线程,但我不这么认为......

最少可重现的非工作代码:

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

【问题讨论】:

  • 好吧,我用sys.exit(0) 代替exit()。要了解有关差异的更多信息,请阅读this。此外,错误只是告诉您该功能想要关闭程序。仅此而已
  • @TheLizzard,我明白,但它不会让你关闭程序。因此,该功能无法正常工作。此外,当exit() 显示错误时,而不是0,值为None
  • 我认为您应该忽略该错误,因为从技术上讲,每次关闭任何 python 程序都会引发错误,这就是它关闭的方式。
  • 我会很高兴,但只有她继续徘徊在两个“世界”之间并加载系统
  • 我不太熟悉pystray 的工作原理,但您可以设置一个全局变量,当变量为True 时,您可以在该函数之外调用exit()?如果这不起作用,我就没有主意了

标签: python python-3.x multithreading tkinter pystray


【解决方案1】:

sys.exit() 将不起作用,因为它不是从主线程或其他东西执行的。 需要使用icon.stop()关闭pystray的事件循环,从而停止整个程序。

【讨论】:

  • icon.stop() 在设置参数提供给“运行”方法时不起作用。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2023-03-09
  • 2023-03-19
  • 2020-01-29
  • 2013-08-11
  • 2022-01-24
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多