如何让pyinstaller打包的exe程序后台运行并显示在系统托盘
实现PyQt/Tkinter程序关闭后缩至系统托盘的方案
核心逻辑是重写GUI框架的窗口关闭事件回调,点击关闭时不触发程序退出,仅隐藏主窗口,同时在系统托盘区注册常驻图标,绑定右键菜单/点击事件来重新唤起主窗口、执行退出等操作,实现和Discord一致的交互效果。
1. PyQt5/PyQt6 实现方案
这是最常用的方案,Qt原生支持系统托盘能力,不需要额外安装第三方依赖:
import sys from PyQt5.QtWidgets import (QApplication, QMainWindow, QSystemTrayIcon, QMenu, QAction, QStyle) from PyQt5.QtCore import Qt class MainWindow(QMainWindow): def __init__(self): super().__init__() self.setWindowTitle("托盘测试程序") self.resize(400, 300) # 初始化托盘配置 self.init_tray() def init_tray(self): # 初始化托盘实例 self.tray_icon = QSystemTrayIcon(self) # 设置托盘图标,可替换为自定义ico文件路径 self.tray_icon.setIcon(self.style().standardIcon(QStyle.SP_ComputerIcon)) # 配置托盘右键菜单 tray_menu = QMenu() # 打开主界面选项 show_action = QAction("打开主界面", self) show_action.triggered.connect(self.show_window) # 彻底退出程序选项 quit_action = QAction("退出程序", self) quit_action.triggered.connect(self.quit_app) tray_menu.addAction(show_action) tray_menu.addAction(quit_action) self.tray_icon.setContextMenu(tray_menu) # 绑定左键点击托盘唤起窗口的逻辑 self.tray_icon.activated.connect(self.on_tray_activated) # 显示托盘图标 self.tray_icon.show() def closeEvent(self, event): # 拦截关闭事件,隐藏窗口而非退出程序 event.ignore() self.hide() # 可选:弹出气泡提示用户程序已缩至托盘 self.tray_icon.showMessage( "提示", "程序已缩小到系统托盘", QSystemTrayIcon.Information, 2000 ) def show_window(self): # 唤起主窗口并置顶 self.show() self.raise_() self.activateWindow() def on_tray_activated(self, reason): # 左键点击托盘直接打开主窗口 if reason == QSystemTrayIcon.Trigger: self.show_window() def quit_app(self): # 彻底退出程序的逻辑 self.tray_icon.hide() QApplication.quit() sys.exit() if __name__ == "__main__": app = QApplication(sys.argv) # 必须加该配置,否则Windows下关闭最后一个窗口会自动退出程序 app.setQuitOnLastWindowClosed(False) window = MainWindow() window.show() sys.exit(app.exec_())
2. Tkinter 实现方案
如果使用Tkinter开发,需要额外安装pystray和pillow库处理托盘逻辑:
- 先安装依赖:
pip install pystray pillow - 示例代码:
import tkinter as tk from pystray import MenuItem as item, Icon from PIL import Image import sys def quit_window(icon, item): icon.stop() root.destroy() sys.exit() def show_window(icon, item): icon.stop() root.deiconify() def on_closing(): # 点击关闭按钮时隐藏窗口,启动托盘 root.withdraw() image = Image.open("app_icon.ico") # 替换为你自己的ico图标路径 menu = (item('打开主界面', show_window), item('退出程序', quit_window)) icon = Icon("test", image, "托盘测试程序", menu) icon.run() root = tk.Tk() root.title("Tkinter托盘测试") root.geometry("400x300") # 绑定关闭事件的自定义回调 root.protocol('WM_DELETE_WINDOW', on_closing) root.mainloop()
3. PyInstaller 打包注意事项
- 打包时需要把用到的自定义ico图标一起打包进exe,Windows下使用
--add-data "app_icon.ico;."参数 - 打包时添加
--windowed参数可以去掉控制台黑框,最终打包命令示例:pyinstaller --windowed --icon=app_icon.ico --add-data "app_icon.ico;." main.py - 打包后的exe运行时,关闭主窗口后会自动出现在任务栏右下角的隐藏图标区,左键点击直接唤起主界面,右键可以调出菜单选择退出程序。
内容的提问来源于stack exchange,提问作者Kyroic
相关产品推荐
相关产品推荐

