将python打包成可执行exe
将python打包的方式大概分为2种,其中每一种都可以简单打包和压缩打包(压缩打包就是构件单独的环境,将项目不需要的包隔离出去)
- 单个文件的打包
- 多个文件的打包(当面对一个大项目的时候,为了方便维护,通常将代码分到不同的文件中。多个文件同时打包的时候,就可以避免原代码泄露)
1.单个文件的打包
单独虚拟环境打包:创建一个单独的虚拟环境,只将文件需要的包进行打包。打包之后的exe相对较小
创建虚拟环境:
conda create -n “name” python=3.9
安装相关的包(程序中用到的包)
pip install ”name“
再进行打包就可以了。
打包成单个文件且不显示控制台窗口:
pyinstaller --onefile --windowed converter.py
如果你想添加图标:
pyinstaller --onefile --windowed --icon=your_icon.ico converter.py
如果你想让生成的文件更小,可以使用以下命令:
(这条命令的作用是将 converter.py 脚本打包成一个单独的、无控制台窗口的可执行文件,并在打包过程中不使用 UPX 压缩,同时清理掉旧的构建文件。这样生成的可执行文件适合用于 GUI 应用程序,并且在某些情况下可能更稳定(因为没有使用 UPX 压缩))
pyinstaller --onefile --windowed --clean --noupx converter.py
2.打包多个文件
默认情况下,PyInstaller 会创建一个包含多个文件的输出,而不是单个 .exe 文件。您只需不使用 --onefile 选项即可。
会在 dist 目录中创建一个名为 TSS的文件夹,其中包含所有必要的文件和库。代码中使用到的库不会被打包到exe中,这大大减少了exe的体积。
注意:保证你打包的.py为程序的入口
(无自定义图标)
pyinstaller --name=TSS --windowed main.py
(有自定义图标)
pyinstaller --name=TSS --windowed --clean --icon=your_icon.ico main.py
上述打包方式,只会在exe上显示图标。并不会在程序运行时,在状态栏和程序头部显示图标。以下是实现上述缺陷的办法。
1,首先在 ThymomaSegmentationApp 类中添加图标设置:
(程序运行时,显示在头部)
# thymoma_segmentation_app.py
from PyQt5.QtGui import QIcon
from PyQt5.QtWidgets import QMainWindow, QPushButton, QVBoxLayout, QHBoxLayout, QWidget, QFileDialog, QLabel, QProgressBar
class ThymomaSegmentationApp(QMainWindow):
def __init__(self):
super().__init__()
self.output_dir = None
self.image_files = []
self.current_index = 0
self.zoom_factor = 1.0
# 设置应用程序图标
icon_path = "path/to/your/icon.ico" # 替换为您的图标路径
self.setWindowIcon(QIcon(icon_path)) # 设置窗口图标
self.initUI()
self.loadModel()
def initUI(self):
# 现有的 initUI 代码...
2,在打包时设置图标:
pyinstaller --name=ThymomaSegmentation ^
--windowed ^
--icon=path/to/your/icon.ico ^
--add-data "path/to/your/icon.ico;." ^
main.py
3,在主程序入口点设置任务栏图标:
(保证任务栏显示图标)
# main.py
import sys
import ctypes
from PyQt5.QtWidgets import QApplication
from PyQt5.QtGui import QIcon
from thymoma_segmentation_app import ThymomaSegmentationApp
def main():
app = QApplication(sys.argv)
# 设置应用程序 ID(Windows)
if sys.platform == 'win32':
myappid = 'company.product.subproduct.version' # 自定义的应用程序 ID
ctypes.windll.shell32.SetCurrentProcessExplicitAppUserModelID(myappid)
# 设置应用程序图标
app_icon = QIcon("path/to/your/icon.ico")
app.setWindowIcon(app_icon)
window = ThymomaSegmentationApp()
window.show()
sys.exit(app.exec_())
if __name__ == '__main__':
main()
4,为了确保图标文件被正确打包和加载,您可以创建一个资源文件:
# resources.py
import os
import sys
def get_resource_path(relative_path):
"""获取资源文件的绝对路径"""
if hasattr(sys, '_MEIPASS'):
# PyInstaller 创建临时文件夹,将路径存储在 _MEIPASS 中
base_path = sys._MEIPASS
else:
base_path = os.path.abspath(".")
return os.path.join(base_path, relative_path)
5,然后在应用程序中使用这个函数:
# thymoma_segmentation_app.py
from resources import get_resource_path
class ThymomaSegmentationApp(QMainWindow):
def __init__(self):
super().__init__()
# ...
# 使用资源路径加载图标
icon_path = get_resource_path("icon.ico")
self.setWindowIcon(QIcon(icon_path))
# ...
6,如果您想要更完整的图标支持,可以创建一个 .rc 文件:
// app.rc
IDI_ICON1 ICON DISCARDABLE "icon.ico"
然后使用 pyrcc5 将其编译为 Python 模块:
pyrcc5 app.rc -o app_rc.py
7,最后,在打包时包含所有必要的文件:
pyinstaller --name=ThymomaSegmentation ^
--windowed ^
--icon=icon.ico ^
--add-data "icon.ico;." ^
--add-data "app_rc.py;." ^
main.py
完整目录结构
your_project/
│
├── main.py
├── thymoma_segmentation_app.py
├── resources.py
├── icon.ico
├── app.rc
├── app_rc.py
└── utils/
└── utils.py
perfect!