首页 > 解决方案 > 从系统托盘恢复后,Tkinter 窗口挂起(使用 pystray)

问题描述

我正在用 Python 创建一个基于 Tkinter 的 GUI。我希望窗口在最小化时隐藏到系统托盘(使用pystray模块)。它隐藏了,但它只出现在屏幕上并挂起,当我试图恢复它时。

这是我尝试过的:

from tkinter import *

from PIL import Image
import pystray


def hide_to_tray(_event=None):
    tray_icon = pystray.Icon("MyTrayIcon", title="My tray icon")  # create the tray icon
    tray_icon.icon = Image.open("app_icon.ico")  # open the icon using PIL
    tray_icon.menu = pystray.Menu(pystray.MenuItem("Open", lambda: tray_icon.stop(), default=True))  # create the menu
    root.withdraw()  # hide the window
    tray_icon.run()  # run the icon's main loop
    # icon mainloop
    root.deiconify()  # when the icon mainloop had been stopped, show the window again
    root.focus_force()  # focus on it

root = Tk()
btn = Button(root, text="Sample button")
btn.grid()
root.bind("<Unmap>", hide_to_tray)  # hide to tray on minimizing
root.mainloop()

我怎么解决这个问题?

标签: pythontkinter

解决方案


1.使用infi.systray

它在单独的线程上运行,因此不会阻塞,使用 pip 安装它:

pip install infi.systray

不要从info.systray线程调用 tkinter 方法:

由于infi.systray在单独的线程上运行,因此您不能在创建时传递给系统托盘图标的回调函数中直接调用 tkinter 方法。使用线程安全的方式(例如queue)来通知主线程有关系统托盘图标中的事件!

2.不要pystray同时tkinter

您不能同时运行它们,因为它们会阻塞正在运行的线程并且都必须在主线程上运行。请参阅Osher 的答案,该答案仅在 tkinter 应用程序关闭时显示系统托盘图标。


推荐阅读