python - 从系统托盘恢复后,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()
我怎么解决这个问题?
解决方案
1.使用infi.systray
它在单独的线程上运行,因此不会阻塞,使用 pip 安装它:
pip install infi.systray
不要从info.systray
线程调用 tkinter 方法:
由于infi.systray
在单独的线程上运行,因此您不能在创建时传递给系统托盘图标的回调函数中直接调用 tkinter 方法。使用线程安全的方式(例如queue)来通知主线程有关系统托盘图标中的事件!
2.不要pystray
同时tkinter
跑
您不能同时运行它们,因为它们会阻塞正在运行的线程并且都必须在主线程上运行。请参阅Osher 的答案,该答案仅在 tkinter 应用程序关闭时显示系统托盘图标。
推荐阅读
- continuous-integration - Gitlab CI 使用规则启用合并结果
- reactjs - 无法获得 componentDidUpdate 内部方法的测试覆盖率
- .net - Yocto Linux 内核:如何将 .NET 核心框架构建到我的 Linux 映像中?
- flutter - 将变量转移到其他类
- java - 是否可以从 dto 和 User 类创建一个 newUser ?
- python - Seaborn 小提琴图与 x 轴标签不对齐
- r - 是否有任何简单/基本的方法可以使用 R 拆分文本转录本?
- html - 如何使用 2 列中的第一项制作响应式网格?
- r - 如何在不构建或安装包的情况下运行 R 包测试?
- flutter - Flutter在滚动时隐藏搜索文本字段