落地苦瓜 2024-08-08 11:32 采纳率: 25%
浏览 6

Python tkinter托盘问题

请问我的代码为什么不能按预期执行

代码如下:

import tkinter as tk
from tkinter import ttk
from tkinter import messagebox as msgbox

try:
    import pystray as stray
    from PIL import Image
    from pystray import MenuItem, Menu
except:
    from pip import main
    main(['install', 'pystray'])
    main(['install', 'Pillow'])
    
    import pystray as stray
    from PIL import Image
    from pystray import MenuItem, Menu
    
    del main

import threading

if 'beta' in __version__:
    msgbox.showinfo('提示', '当前为测试版本,请勿小心使用!')
if 'FENG GOU' in __version__:
    msgbox.showinfo('提示', '当前为疯狗版本,请勿小心使用!')


LOGO_PATH = 'D:\\code\\Python MC 服务器自动卖线\\icon.ico'
IMAGE = Image.open(LOGO_PATH)
TITLE = 'Python MC 服务器自动卖东西'

win = tk.Tk()

SCREENWIDTH = win.winfo_screenwidth()
SCREENHEIGHT = win.winfo_screenheight()
WIDTH = 500
HEIGHT = 500
LEFT = (SCREENWIDTH - WIDTH) / 2
TOP = (SCREENHEIGHT - HEIGHT) / 2

win.geometry(f'{WIDTH}x{HEIGHT}+{int(LEFT)}+{int(TOP)}')
win.resizable(False, False)
win.title(TITLE)
win.iconbitmap(LOGO_PATH)
win.attributes('-topmost', 'false')

TOPMOST = False
TOPMOST_TEXT = '置顶'

def quit_window(icon):
    
    icon.stop()
    win.destroy()


def show_window():

    win.deiconify()


def hide_window():
    
    win.iconify()


def sicky_window():
    
    global TOPMOST
    global TOPMOST_TEXT
    
    if TOPMOST:
        win.attributes('-topmost', 'false')
        TOPMOST = False
        TOPMOST_TEXT = '置顶'
        icon.update_menu()
    else:
        win.attributes('-topmost', 'true')
        TOPMOST = True
        TOPMOST_TEXT = '取消置顶'
        icon.update_menu()


menu = [MenuItem('显示', show_window, default=True), MenuItem('隐藏', hide_window), 
        Menu.SEPARATOR, MenuItem(TOPMOST_TEXT, sicky_window), 
        Menu.SEPARATOR, MenuItem('退出', quit_window)]
icon = stray.Icon('icon', IMAGE, TITLE, menu=menu)

threading.Thread(target=icon.run, daemon=True).start()

win.mainloop()

它无法改变托盘的菜单项文本

  • 写回答

2条回答 默认 最新

  • 鸽芷咕 优质创作者: C/C++技术领域 2024-08-08 11:46
    关注

    你的代码有几个问题需要解决:

    1. 你的代码中使用了pystray库,这是一个第三方库,需要确保已经正确安装。如果没有安装,你的代码中尝试使用pip来安装它,但是这行代码(main(['install', 'pystray']))实际上是在控制台执行pip命令,而不是在Python环境中。因此,它不会在你运行Python脚本时自动执行。你需要先手动安装pystray
    2. 在你的代码中,你尝试导入main函数,但在except块中你删除了这个导入。这可能会导致问题,因为如果你的代码在这个except块执行,它将尝试访问一个已经删除的main函数。
    3. 在代码中,你使用了tryexcept块来尝试导入pystray和它的依赖,但在except块中你又重新导入了它们。这不是必要的,因为在try块中已经成功导入了一次。
    4. 你使用了messagebox来显示信息,但只在特定的版本条件下。这意味着只有当版本字符串包含'beta''FENG GOU'时,这些消息才会显示。这不是问题,但如果你想要在所有情况下显示这些消息,你需要调整代码。
    5. 最后,你的窗口似乎没有正确地显示。这是因为stray.Icon创建了一个托盘图标,但你的win.mainloop()在托盘图标线程之外运行,这意味着你的主窗口将不会显示。你需要将win.mainloop()放在托盘图标线程内部。
      这是一个修改后的代码示例,解决了上述问题:
      import tkinter as tk
      from tkinter import ttk
      from tkinter import messagebox as msgbox
      from pystray import Icon, MenuItem, Menu
      import threading
      # 确保pystray库已正确安装
      try:
       import pystray
       from PIL import Image
      except ImportError:
       import pip
       pip.main(['install', 'pystray'])
       pip.main(['install', 'Pillow'])
       import pystray
       from PIL import Image
      del pip
      def quit_window(icon):
       icon.stop()
       win.destroy()
      def show_window():
       win.deiconify()
      def hide_window():
       win.iconify()
      def toggle_topmost():
       global TOPMOST
       global TOPMOST_TEXT
       TOPMOST = not TOPMOST
       TOPMOST_TEXT = '置顶' if TOPMOST else '取消置顶'
       icon.update_menu()
      menu = [
       MenuItem('显示', show_window, default=True),
       MenuItem('隐藏', hide_window),
       Menu.SEPARATOR,
       MenuItem(TOPMOST_TEXT, toggle_topmost),
       Menu.SEPARATOR,
       MenuItem('退出', quit_window)
      ]
      win = tk.Tk()
      win.resizable(False, False)
      win.title('Python MC 服务器自动卖东西')
      win.iconbitmap('icon.ico')
      SCREENWIDTH = win.winfo_screenwidth()
      SCREENHEIGHT = win.winfo_screenheight()
      WIDTH = 500
      HEIGHT = 500
      LEFT = (SCREENWIDTH - WIDTH) / 2
      TOP = (SCREENHEIGHT - HEIGHT) / 2
      win.geometry(f'{WIDTH}x{HEIGHT}+{int(LEFT)}+{int(TOP)}')
      icon = Icon('icon', Image.open('icon.ico'), 'Python MC 服务器自动卖东西', menu=menu)
      threading.Thread(target=icon.run, daemon=True).start()
      win.mainloop()
      
      请注意,我已经移除了不必要的中间步骤,并确保所有的库都在正确的情况下被导入。我还添加了一个toggle_topmost函数来切换窗口是否置顶,并更新了菜单项的文本。最后,我确保win.mainloop()在托盘图标线程内部运行。
    评论

报告相同问题?

问题事件

  • 创建了问题 8月8日