You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何让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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.26 05:54:08