首页 > 编程语言 >如何将 Python 项目打包成 exe,另带卸载功能!

如何将 Python 项目打包成 exe,另带卸载功能!

时间:2024-04-18 23:22:33浏览次数:32  
标签:rename exe Python text self tk 另带 path

Python 项目打包成 exe

前言

虽然我是做 web 的,但是对 Python 的众多开源项目一直都很关注。像以前的 stable diffusion 的 AI 绘画,和 so-vits-svc 音色替换等源码的部署文档都很完善了。尽管如此,但对于刚入门的和本地环境搭建各种踩坑的同学,急于一试就显得不太友好了。针对这一现象,网上大佬们早有了各种一键部署的解决方案,不用安装 Python 环境,不用下载依赖包,点一下点exe 就可以用。

那他们是怎么做的呢,到这里很多人应该都会说用 pyinstaller。是的,这个确实可以解决整体环境打包,但有时候一些图标和依赖文件要放在一起才能正常使用,就类似于绿色桌面工具了。那有没有方法对这个再做进一步封装,就是点击 exe 后需要安装,然后安装后才是项目的文件,还可以卸载 。这里,我推荐使用Inno Setup Compiler,那么接下来我就用一个 GUI 的小 demo 演示 exe 的完整打包过程。

image

环境

  • Python 3.8

  • Tkinter (自带)

  • pyinstaller 6.3.0

  • Inno Setup Compiler

基本流程

用 conda 单独创建一虚拟环境,比如写一个 tkinter 应用,对了为了好看,我们可以设置以下 icon,尺寸 32x32,大图标 64x64 准备一下即可。然后用 pyinstaller 将应用达成文件包 (含 exe),最后用 Inno Setup Compiler 达成安装包,里面就是各种文件关联,图标和信息的设置了。
image

开始操作

环境创建

# 1. 创建环境
conda create -n tools_env python=3.8
	
# 2. 进入环境
conda activate tools_env
	
# 3. 安装 pyinstaller
pip install pyinstaller -i https://pypi.tuna.tsinghua.edu.cn/simple

编码示例

import tkinter as tk
from tkinter import ttk
from tkinter import messagebox
from ToolTip import ToolTip
import os
import time


class Application(tk.Tk):

    def __init__(self):
        super().__init__()
        self.title("公众号:ZERO开发")
        self.iconbitmap('logo.ico')
        self.geometry("600x370")  # 设置固定的窗口大小
        self.resizable(False, False)  # 禁止调整窗口大小
        self.style = ttk.Style(self)
        self.main_color = self.cget("bg")

        self.style.configure("TEntry",
                             padding=6,
                             relief="flat",
                             background="#0078d7",
                             foreground="black",
                             font=("Arial", 12, "bold"))

        self.style.configure("TLabel",
                             font=("Arial", 12, "bold"))

        self.style.configure("TButton",
                             padding=6,
                             font=("Arial", 12))

        self.create_widgets()

    def create_widgets(self):
        self.path_label = ttk.Label(self, text='绝对路径:')
        self.path_label.grid(row=0, sticky=tk.W, pady=30, padx=20)

        self.path = tk.StringVar()
        self.path_entry = ttk.Entry(self, width=60, textvariable=self.path)
        self.path_entry.grid(row=0, column=1, sticky=tk.E, pady=5)
        ToolTip(self.path_entry, "电脑里的目录路径,如 D:\\3code\\6pytorch\pytorch_ai_demo")

        self.rename_label = ttk.Label(self, text='修改名称:')
        self.rename_label.grid(row=1, sticky=tk.W, pady=5, padx=20)

        self.rename = tk.StringVar()
        self.rename_entry = ttk.Entry(self, width=60, textvariable=self.rename)
        self.rename_entry.grid(row=1, column=1, sticky=tk.E, pady=5)

        self.msg_text = tk.Text(self, height=2, width=60, wrap='none')  # 添加一个列表框来显示文件名
        self.msg_text.grid(row=2, column=1, sticky=tk.W, pady=15)
        self.msg_text.configure(bd=0, relief="solid", bg=self.main_color)
        # self.msg_text.insert(tk.END, "这是要显示的文本。")

        ttk.Button(self, text='确认修改', command=self.start_program).grid(row=3, column=1, sticky=tk.W, pady=20, padx=120)
        ttk.Button(self, text='关于作者', command=self.about).grid(row=4, column=1, sticky=tk.W, padx=120)

    def start_program(self):
        print("绝对路径:{}, 重命名:{}". format(self.path.get(), self.rename.get()))

        path = self.path.get()
        rename = self.rename.get()

        if path == "" or rename == "":
            messagebox.showwarning("警告", "输入框不能为空!")
            return

        if os.path.isdir(path) == False:
            messagebox.showwarning("警告", "绝对路径不正确!")
            return

        i = 0
        # '该文件夹下所有的文件(包括文件夹)'
        FileList = os.listdir(path)

        # '遍历所有文件'
        for files in FileList:
            oldDirPath = os.path.join(path, files)

            self.msg_text.delete(1.0, tk.END)
            self.msg_text.insert(tk.END, oldDirPath)

            # '如果是文件夹则递归调用'
            if os.path.isdir(oldDirPath):
                self.start_program(oldDirPath)

            # '文件名'
            fileName = os.path.splitext(files)[0]
            # '文件扩展名'
            fileType = os.path.splitext(files)[1]
            fileType = fileType.lower()

            newDirPath = os.path.join(path, rename + "_" + str(i) + fileType)

            # '重命名'
            os.rename(oldDirPath, newDirPath)
            i += 1

        messagebox.showinfo("信息", "操作完成!")

    def about(self):
        messagebox.showinfo("关于", "微信公众号:ZERO开发\r\n\r\n工具:批量修改文件1.0")

    def quit_program(self):
        self.destroy()


if __name__ == "__main__":
    app = Application()
    app.mainloop()

开始打包

pyinstaller -F -w Application.py -–icon=logo.ico

image
这里我们希望打包是自己的图标就带上 icon,而且打开时不要出现黑色闪框就带上 w,当然后面打开 exe 要把 icon 放到与他同一级的目录中,尺寸上面已经说了,下面是参数说明。

参数说明:	
-–icon=图标路径
-F 打包成一个exe文件
-w 使用窗口,无控制台
-c 使用控制台,无窗口
-D 创建一个目录,里面包含exe以及其他一些依赖性文件

还有一个问题是,如果是修改了代码,需要反复多次打包,可以把项目前一次打包生成的生成的 spec 后缀文件删除即可。打包成功后,控制面包会显示 Building EXE from EXE-00.toc completed successfully,然后根目录的 dist 就是打包后的文件包,里面需要的文件图片等都在里面,后面用 Inno Setup Compiler 也就是对这个文件夹打包。
image

image

Inno Setup Compiler 操作

新建脚本,填写信息

image

选择主程序和需要的文件

image

设置名称和 icon

image

选择导出位置 (前面还有协议等设置)

image

运行脚本开始生成

image

安装打开,安装目录里有自带卸载程序

image

END

原文公众号:ZERO开发

标签:rename,exe,Python,text,self,tk,另带,path
From: https://www.cnblogs.com/Ivanky/p/18144743

相关文章

  • python 将 CVS文件转为HTML文件
    importpandasaspdimportosdefcsv_to_html(csv_file_path,html_file_path):"""将CSV文件转换为HTML文件。:paramcsv_file_path:CSV文件的路径。:paramhtml_file_path:要创建的HTML文件的路径。"""#读取CSV文件df=pd.read......
  • Python安装gensim报错解决
    Python环境安装gensim,pipinstallgensim之后,buildC/C++代码阶段报错:error:‘for’loopinitialdeclarationsareonlyallowedinC99mode出现上面的报错,原因在于:gensim安装包代码中存在C/C++程序,需要本地编译C/C++代码,编译器默认非C99模式,因此语法不兼容;为了编译......
  • reg2inf.exe 是一个 Windows 实用工具,用于将 Windows 注册表文件 (.reg) 转换为 Windo
    reg2inf.exe是一个Windows实用工具,用于将Windows注册表文件(.reg)转换为WindowsINF文件(.inf)。INF文件是一种文本文件,通常用于在Windows操作系统中安装设备驱动程序和配置设置。使用reg2inf.exe工具可以将注册表中的配置转换为INF格式,从而可以在Windows......
  • Python数据分析 Series 笔记
      002,pandas介绍  003,Series创建导入Pandas Series是一种类似于一维数组的对象,由下面两个部分组成:values:一组数据(ndarray类型)index:相关的数据索引标签(3.1)Series的创建两种创建方式:(1)由列表或Numpy数组创建默认索引为0到N-1的整数型索引 index和val......
  • Blender自带的Python环境中安装Pandas模块
    要在Blender自带的Python环境中安装Pandas模块,你可以按照以下步骤操作:找到Blender的Python可执行程序位置:在Windows系统中,默认路径可能是类似于C:\ProgramFiles\BlenderFoundation\Blender3.1\3.1\python\bin\python.exe的路径,其中3.1是Blender的版本号,具体路径会随着Blende......
  • 开源Python几何约束求解器GeoSolver
    GeoSolver是一个用于几何约束求解的Python包。几何约束问题(GCP)是几何变量上/之间的一组几何约束。问题是找到几何变量的配置以满足所有约束。几何变量是位置、方向、形状、大小等未知的对象。GCP中的变量可以是点、线、平面、球体、圆柱体和更复杂的形状。几何约束是诸如对象......
  • Effective Python:第7条 尽量用enumerate取代range
    Python有个内置的函数,叫作enumerate。enumerate能够把任何一种迭代器(iterator)封装成惰性生成器(lazygenerator)。这样的话,每次循环的时候,它只需要从iterator里面获取下一个值就行了,同时还会给出本轮循环的序号,即生成器每次产生的一对输出值。下面通过内置的next函数手动推进enumera......
  • 推荐一个计算Grad-CAM的Python库
    前言类激活图CAM(classactivationmapping)用于可视化深度学习模型的感兴趣区域,增加了神经网络的可解释性。现在常用Grad-CAM可视化,Grad-CAM基于梯度计算激活图,对比传统的CAM更加灵活,且不需要修改模型结构。虽然计算grad-cam并不复杂,但是本着能导包就导包的原则,想着去用现成的......
  • Effective Python:第6条 把数据结构直接拆分到多个变量里,不要专门通过下标访问
    使用拆分(unpacking),就可以把元组里面的元素分别赋给多个变量。优点:1,通过unpacking来赋值要比通过下标去访问元组内的元素更清晰,而且这种写法所需的代码量通常比较少。2,便于原地交换两个变量;tb=[1,2]tb[0],tb[1]=tb[1],tb[0]print(tb)3,for循环或者类似的结构(例如推......
  • python包:matplotlib
    1):matplotlib是一个python2D绘图库,利用它可以画出许多高质量的图像。只需几行代码即可生成直方图,条形图,饼图,散点图等。Matplotlib是整个包,pyplot是Matplotlib中的一个模块,并且pylab是一个安装在一起的模块。 https://matplotlib.org/2:使用https://zhuanlan.zhihu.com/p......