import threading import pystray from PIL import Image from tkinter import Tk, PhotoImage, Menubutton, Menu, Toplevel, Button, Label, LabelFrame class GUI: def __init__(self): # 图标 self.iconphoto_path = './xxxx.ico' self.root = Tk() self.root.title("标题") # 弹窗图片 self.question_png = './question.png' self.photo = PhotoImage(file=self.question_png) # 设置窗体尺寸并居屏幕中心 self.width, self.height = 450, 400 screen_width = self.root.winfo_screenwidth() screen_height = self.root.winfo_screenheight() window_size = f'{self.width}x{self.height}+{round((screen_width - self.width) / 2)}+{round((screen_height - self.height) / 2)}' self.root.geometry(window_size) # 图标默认值 self.icon = None # 窗口不可拉伸 # self.root.resizable(0, 0) # alpha 越小透明度越高 self.root.attributes('-alpha', 1.0) # 设置图标 self.root.iconphoto(False, PhotoImage(file=self.iconphoto_path)) self.top0 = None self.show() # 关闭窗口,弹窗提醒 self.withdraw_window() self.root.protocol('WM_DELETE_WINDOW', self.withdraw_window) self.root.mainloop() def show(self): # 创建一个菜单按钮 menubtn = Menubutton(self.root, text='点击进行操作', relief='groove') # 设置位置(布局) menubtn.grid(padx=195, pady=105) # 添加菜单,使用 tearoff 参数不显示分割线 filemenu = Menu(menubtn, tearoff=False) filemenu.add_command(label='新建') filemenu.add_command(label='删除') filemenu.add_command(label='复制') filemenu.add_command(label='保存') # 显示菜单,将菜单命令绑定在菜单按钮对象上 menubtn.config(menu=filemenu) def quit_window(self): # 关闭程序 self.icon.stop()# 停止 Pystray 的事件循环 self.root.quit() self.root.destroy() def show_window(self): # 显示窗口 if self.root.state() == 'withdrawn': self.root.deiconify() # 显示窗口 else: self.root.withdraw() # 隐藏窗口 def show_notify(self, title="消息", content="未有新消息"): # 弹窗提示消息 flug = False if not self.icon.visible: self.icon.visible = True# 显示图标 flug = True self.icon.notify(content, title) if flug: self.icon.visible = False# 隐藏图标 def mini_window(self, child_window): # 最小化到托盘 # 关闭弹窗 child_window.destroy() # 停止展示图标 if self.icon: self.icon.visible = False# 隐藏图标 # 隐藏窗口 self.root.withdraw() def cancel_window(self, child_window): child_window.destroy() # 停止展示图标 if self.icon: self.icon.visible = False def close_dialog(self): # 关闭提醒 self.root.overrideredirect(False) child_window = Toplevel(self.root) width = self.root.winfo_screenwidth() height = self.root.winfo_screenheight() child_window.geometry(f'320x150+{int(width/2)+400}+{int(height/2)-350}') child_window.title("title") child_window.iconphoto(False, PhotoImage(file=self.iconphoto_path)) frame = LabelFrame(child_window, text='', labelanchor="n", font=("YAHEI", 12)) frame.place(relwidth=1.0, relheight=1.0) # 加载图片 lab = Label(frame, image=self.photo, font=('微软雅黑', 15, 'italic')) lab.place(relx=0.12, rely=0.2, relwidth=0.15, relheight=0.35) label = Label(frame, text='是否确认关闭程序?', compound='left', width=16) label.place(relx=0.25, rely=0.2, relwidth=0.5, relheight=0.35) button1 = Button(frame, text='关闭程序', width=10, command=lambda: self.root.quit()) button1.place(relx=0.03, rely=0.7, relheight=0.2, relwidth=0.25) button2 = Button(frame, text='最小化到托盘', width=10, command=lambda: self.mini_window(child_window)) button2.place(relx=0.32, rely=0.7, relheight=0.2, relwidth=0.35) button3 = Button(frame, text='取消', width=10, command=lambda: self.cancel_window(child_window)) button3.place(relx=0.71, rely=0.7, relheight=0.2, relwidth=0.25) child_window.attributes('-topmost', True)# 窗口顶置 def withdraw_window(self): if self.icon: self.close_dialog() # result = tkinter.messagebox.askyesnocancel(title="标题", message="是否确认关闭程序?") # if result: # self.root.quit() # # 停止展示图标 # self.icon.stop() # # 隐藏窗口 # self.root.withdraw() menu = pystray.Menu(pystray.MenuItem('显示', self.show_window, default=True), pystray.MenuItem(text='最近通知', action=lambda event:self.show_notify()), pystray.Menu.SEPARATOR, pystray.MenuItem('退出', self.quit_window)) image = Image.open(self.iconphoto_path) self.icon = pystray.Icon("icon", image, "title", menu) threading.Thread(target=self.icon.run, daemon=True).start()
在线工具 - 你的工具箱 在线抠图,图标制作 question.png GUI()