繁体   English   中英

程序结束时如何销毁图标托盘

[英]How to destroy the icon tray when the program ends

我有一个在我的 .py 程序启动时调用的类,它在 Windows 任务栏中创建一个图标托盘。 其中,有选项quit ,它映射到我的类中的函数kill_icon_tray ,它应该终止 Icon 然后完成我的程序。

这是类(一些方法被省略,因为它们不需要):

from infi.systray import SysTrayIcon

class Tray_icon_controller:

    def __init__(self):
        self.menu_options = (("Open Chat Monitor", None, self.open_chat),)
        self.systray = SysTrayIcon("chat.ico", "Engineer Reminder", self.menu_options, on_quit=self.kill_icon_tray);

    def init_icon_tray(self):
        self.systray.start();

    def kill_icon_tray(self, systray):
        self.systray.shutdown()

但是,每当我单击图标托盘中的quit时,都会返回以下异常:

$ py engineer_reminder.py
Traceback (most recent call last):
  File "_ctypes/callbacks.c", line 237, in 'calling callback function'
  File "C:\Users\i866336\AppData\Local\Programs\Python\Python38-32\lib\site-packages\infi\systray\traybar.py", line 79, in WndProc
    self._message_dict[msg](hwnd, msg, wparam.value, lparam.value)
  File "C:\Users\i866336\AppData\Local\Programs\Python\Python38-32\lib\site-packages\infi\systray\traybar.py", line 195, in _destroy
    self._on_quit(self)
  File "C:\Users\i866336\Documents\GitHub\chat_reminder\cl_tray_icon_controller.py", line 17, in kill_icon_tray
    self.systray.shutdown()
  File "C:\Users\i866336\AppData\Local\Programs\Python\Python38-32\lib\site-packages\infi\systray\traybar.py", line 123, in shutdown
    self._message_loop_thread.join()
  File "C:\Users\i866336\AppData\Local\Programs\Python\Python38-32\lib\threading.py", line 1008, in join
    raise RuntimeError("cannot join current thread")
RuntimeError: cannot join current thread

我尝试将方法kill_icon_tray修改为此,但它抛出了相同的异常:

    def kill_icon_tray(self, systray):
        self.systray.shutdown()

根据infi.systray文档,我做对了:

要在程序结束时销毁图标,请调用systray.shutdown()

所以我不确定我在这里错过了什么......有人可以帮忙吗? 谢谢!

遇到与您相同的问题,您可以找到解决方案,但对于其他遇到相同问题的人。

为我修复的是将 systray.shutdown() 更改为 SysTrayIcon.shutdown

    def kill_icon_tray(systray):
    SysTrayIcon.shutdown

希望这可以帮助

万一其他人遇到过这个问题,修补SysTrayIcon.shutdown方法就是为我修复它的方法。

from infi.systray import SysTrayIcon
from infi.systray.traybar import PostMessage, WM_CLOSE


# Remove the thread.join from the SysTrayIcon.shutdown function
def custom_shutdown(self):
    if not self._hwnd:
        return      # not started
    PostMessage(self._hwnd, WM_CLOSE, 0, 0)
    #self._message_loop_thread.join()

# Overwrite shutdown function
SysTrayIcon.shutdown = custom_shutdown

# Use it as normal
sys_tray.shutdown()

我不确定为什么会发生这个问题。 在我的情况下,我在SysTrayIcon对象的生命周期中创建并完成了守护进程,但在创建它们之前,我可以将SysTrayIcon._message_loop_function.join()成功连接到MainThread ,但在我无法...

无论如何,单独调用PostMessage(self._hwnd, WM_CLOSE, 0, 0)似乎也有效。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM