【问题标题】:Tkinter window hangs after restoring from system tray (using pystray)从系统托盘恢复后,Tkinter 窗口挂起(使用 pystray)
【发布时间】:2019-12-05 19:35:04
【问题描述】:

我正在用 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()

我该如何解决这个问题?

【问题讨论】:

    标签: python tkinter


    【解决方案1】:

    1。使用infi.systray

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

    pip install infi.systray
    

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

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

    2。不要同时运行pystraytkinter

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

    【讨论】:

    • 有没有办法在主线程之外的另一个线程中运行 tkinter 或 pystray,而不是通过队列相互通信?
    • 我认为 pystray 和 tkinter 只能在主线程上运行,遗憾的是
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-06-21
    • 1970-01-01
    • 1970-01-01
    • 2010-10-06
    • 2019-07-17
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多