pyinstaller——关于含有图片GUI程序的封装(打包)

一、简介

我们写完一个程序,一般都是封装后给用户使用,因为有些用户机台环境不满足py文件的执行,重新安装较为麻烦。
程序封装命令如下:

  1. 封装为.exe文件,运行时带有cmd黑框(xxx.py表示将要封装的程序)

pyinstaller -F xxx.py

  1. 封装为exe文件,运行未带cmd黑框

pyinstaller -F -w xxx.py

但是GUI程序基本都带有图片资源,还按这样方式封装后运行会直接报错,因为图片没有封装上

注:py文件在window系统封装都是”.exe“文件。

二、GUI程序封装流程
  1. 将图片放入”resources“文件夹中,然后运行py文件确保程序无异常(”resources“文件夹名字为任意命名的);

  2. 【创建spec文件】由于本次的程序打包需要进行resources资源引用,所以必须手工的在打包配置文件之中进行资源路径定义, 就需要根据打包程序生成有一个"*.spec"文件;
    如图是待打包程序
    在这里插入图片描述
    注:这里将图片已放入resources目录下,然后执行如下步骤:
    (1) 用cmd命令切换窗口切换至gui目录下;
    (2) 运行命令 pyi-makespec -F demo.py ,会产生如下提示,代表创建spec文件创建成功。
    在这里插入图片描述

  3. 在待打包的py文件中修改部分代码;
    原demo.py文件如下:

from tkinter import *                  


root = Tk()
textlabel = Label(root,text='一个窗口,\n哈哈!',   #支持\n换行
                  justify=LEFT,                    #表示文字左对齐
                  padx=20)                         #表示边距为20
textlabel.pack(side=LEFT)                          #自动排放,side=LEFT为排放在左边

#显示图片,图片支持gif
photo = PhotoImage(file='./resources/001.gif')
imglabel = Label(root,image=photo)
imglabel.pack(side=RIGHT)                         #自动排放,side=RIGHT为排放在右边边


mainloop()

修改后的py文件

from tkinter import *                
import os


def get_resource_path(relative_path):
    if getattr(sys, 'frozen', False):
        base_path = sys._MEIPASS
    else:
        base_path = os.path.abspath('.')
    return os.path.join(base_path, relative_path)
logo_path = get_resource_path(os.path.join('resources', '001.gif'))

root = Tk()
textlabel = Label(root,text='一个窗口,\n哈哈!',  
                  justify=LEFT,                     
                  padx=20)                          
textlabel.pack(side=LEFT)           

#显示图片,图片支持gif
photo = PhotoImage(file=logo_path)
imglabel = Label(root,image=photo)
imglabel.pack(side=RIGHT)         

mainloop()
  1. 修改【demo.spec】文件定义要使用的资源路径;
    datas=[], 修改为 datas=[("resources","resources")],
  2. 在cmd命令框中运行pyinstaller -F demo.spec
    在这里插入图片描述
  3. 然后在dist文件中即可找到封装后的exe文件,那么在其他机台上使用就不需要带图片运行了。
### 使用Python将音频和图像资源嵌入并生成单个EXE文件 为了实现这一目标,可以采用`PyInstaller`工具来打包Python应用程序及其依赖项成独立的可执行文件。对于静态资源如音乐和图片,则可以通过特定的方式将其集成到最终的应用程序中。 #### 准备工作 确保已经安装了最新版的Python环境[^1]。接着,在命令行界面通过pip安装必要的库: ```bash pip install pyinstaller pillow soundfile ``` 这里使用到了Pillow用于处理图像,而SoundFile则用来管理声音文件。 #### 将资源转换为字节串形式 一种常见的做法是先读取这些多媒体文件的内容作为二进制数据流保存下来,并在运行时再加载出来恢复原貌。下面给出一段简单的例子展示怎样把一张PNG格式的照片以及WAV格式的声音编码成为base64字符串存储起来: ```python import base64 def encode_file_to_base64(file_path): with open(file_path, "rb") as file: encoded_string = base64.b64encode(file.read()).decode('utf-8') return f"data:image/png;base64,{encoded_string}" if file_path.endswith('.png') \ else f"data:audio/wav;base64,{encoded_string}" ``` 此函数能够接受任意类型的文件路径参数,并返回相应的Base64编码后的URL字符串表示法。 #### 创建GUI应用框架 假设要创建一个带有按钮的小窗口,点击之后会播放指定曲目并且显示对应的封面画作。那么可以借助tkinter模块快速搭建起这样的交互界面: ```python from tkinter import Tk, Button, Label from PIL import ImageTk, Image import io import base64 import sounddevice as sd import numpy as np from scipy.io.wavfile import read class App(Tk): def __init__(self, image_data, audio_data): super().__init__() self.title("Media Player") # Decode and display the image from Base64 string. img_bytes = base64.b64decode(image_data.split(',')[1]) pil_image = Image.open(io.BytesIO(img_bytes)) tk_img = ImageTk.PhotoImage(pil_image) label = Label(self, image=tk_img) label.image = tk_img # Keep a reference to avoid garbage collection issues. label.pack() play_button = Button( text="Play Music", command=lambda: self.play_audio(audio_data), width=20, height=3 ) play_button.pack() @staticmethod def play_audio(base64_str): sample_rate, data = read(io.BytesIO(base64.b64decode(base64_str.split(',')[1]))) duration_seconds = len(data)/sample_rate try: sd.play(np.array(data), samplerate=int(sample_rate)) sd.wait(duration_seconds) except Exception as e: print(f"Error playing audio: {e}") ``` 这段代码定义了一个继承自Tk类的新App类,它接收两个初始化参数——分别是之前提到过的经过编码处理过后的图像与音轨资料;内部实现了当用户按下“Play Music”按键后触发调用play_audio()方法的功能逻辑。 #### 打包项目 最后一步就是利用PyInstaller完成整个工程的一键封装流程啦! 编写main.py脚本来启动上述设计好的图形化组件: ```python if __name__ == '__main__': app = App(IMAGE_BASE64_STRING, AUDIO_BASE64_STRING) app.mainloop() ``` 请注意替换掉这里的占位符变量名(即 IMAGE_BASE64_STRING 和 AUDIO_BASE64_STRING)为你实际拥有的媒体素材所对应的那个独一无二的身份标识码哦~ 随后只需一条指令即可搞定一切后续事宜: ```bash pyinstaller --onefile main.py ``` 这将会自动收集所有必需品并将它们压缩至单一的目标位置下形成名为dist/main.exe的结果产物。
评论 11
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值