当前位置:   article > 正文

如何将写好的python文件导出为exe(新手经历分享)_python系统导出exe

python系统导出exe

前言

大家好,我是北京科技大学的某个学生,因为出差的缘故不得不学习python这门语言,说实话一开始头晕脑胀的,连文件都不会创立,在ChatGPT这位老师(真的很好用,你可以给出输入预期和输出预期,直接帮你生成可行的代码)和某位北航大佬的无私解答下,从零开始构建了一个读取Excel表格数据画图的GUI界面,然后将其打包成为一个exe文件,经过实验可以在没有安装python的电脑上正常运行,鉴于我在打包exe时遇见了种种问题,在网络上搜查资料时也没有找到比较简单详细的教程,就把我自己的一个经历写出来供大家参考吧,希望各位大佬轻喷QAQ。

一、打包工具

python打包工具我用的是pyinstaller,至于介绍的话就不讲了,之前在网上浏览的文章有提到高版本python可能不适用的问题,我也没有遇见(用的3.7版本),下面就介绍打包流程

二、打包流程

1.引入代码

代码如下(我自己写的,比较菜,仅用来举例,大佬勿喷):

import pandas as pd
import matplotlib.pyplot as plt
import tkinter as tk
from tkcalendar import DateEntry
from tkinter import filedialog
from datetime import date
#几个按钮的触发事件设计
#region my code block
# Excel文件打开函数
def import_button_click():
    global df
    file_path = filedialog.askopenfilename(filetypes=[("Excel files", "*.xlsx;*.xls")])
    if file_path:
        # 使用pandas读取Excel文件
        df = pd.read_excel(file_path, engine='openpyxl')
        # print(df)


# 两天绘图按钮2点击
def print_button2_click():
    global df
    df2 = df
    # 得到日历信息
    calenda_data3 = root.date_entry3.get_date()
    calenda_data4 = root.date_entry4.get_date()
    calenda_data3 = pd.to_datetime(calenda_data3)
    calenda_data4 = pd.to_datetime(calenda_data4)

    if calenda_data3 <= calenda_data4:
            NUM = 0
            if NUM == 0:
                dates = pd.to_datetime(df['日期'])
                # print(dates)
                # 绘制每个元素的折线图
                i = -1
                for date in dates:
                    i = i + 1
                    if (date != calenda_data3 and date != calenda_data4):
                        df2 = df2.drop(i)
                # dates = dates[(dates == calenda_data3) | (dates == calenda_data4)]

                df2['日期'] = pd.to_datetime(df2['日期'])
                # 设置日期列为索引
                df2.set_index('日期', inplace=True)
                # 使用 plot 绘制折线图,交换 x 和 y 的位置
                ax=df2.T.plot(marker='o', linestyle='-')
                # 添加标题和标签
                ax.set_xticks(range(0, len(df2.columns)))
                ax.set_xticklabels(df2.columns)  # 设置 x 轴标签为元素的列名
                plt.rcParams['font.sans-serif'] = ['SimHei']  # 设置中文显示
                plt.rcParams['axes.unicode_minus'] = False  # 解决负号显示问题
                plt.title('日期下不同元素的值的变化',fontproperties='SimHei')
                plt.xlabel('元素',fontproperties='SimHei')
                plt.ylabel('日期',fontproperties='SimHei')

                # 显示图形
                plt.show()
            NUM = NUM + 1

    else:print("日期输入错误")


# 一段时间绘图1按钮点击
def print_button_click():
    global df
    df2 = df

    # 得到下拉栏信息
    option_info = selected_option.get()
    # 得到日历信息
    calenda_data1 = root.date_entry1.get_date()
    calenda_data2 = root.date_entry2.get_date()
    calenda_data1 = pd.to_datetime(calenda_data1)
    calenda_data2 = pd.to_datetime(calenda_data2)

    if calenda_data1 <= calenda_data2:
        if option_info == "全元素":
            NUM = 0
            if NUM == 0:
                dates = pd.to_datetime(df['日期'])
                # print(dates)
                # 绘制每个元素的折线图
                i = -1
                for date in dates:
                    i = i + 1
                    if (date < calenda_data1 or date > calenda_data2):
                        df2 = df2.drop(i)
                    # print(df2)
                    # for element in df2.columns[1:]:
                dates = dates[dates >= calenda_data1]
                dates = dates[dates <= calenda_data2]
                for element in df2.columns[1:]:
                    plt.plot(dates, df2[element], label=element)
            # 添加标题、标签和图例,精简x轴数据显示
            unique_x_values = list(set(dates))
            plt.xticks(unique_x_values)
            plt.rcParams['font.sans-serif'] = ['SimHei']  # 设置中文显示
            plt.rcParams['axes.unicode_minus'] = False  # 解决负号显示问题
            plt.title(option_info + '折线图', fontproperties='SimHei')
            plt.xlabel('日期', fontproperties='SimHei')
            plt.ylabel('元素值', fontproperties='SimHei')
            plt.legend(loc='upper right')
            # 格式化日期显示
            plt.gca().xaxis.set_major_formatter(plt.matplotlib.dates.DateFormatter('%Y-%m-%d'))
            # 自动调整日期标签的显示以防止重叠
            plt.gcf().autofmt_xdate()
            # 显示图形
            plt.show()
            NUM = NUM + 1
        if option_info != "全元素":
            NUM = 0
            if NUM == 0:
                dates = pd.to_datetime(df['日期'])
                # print(dates)
                # 绘制每个元素的折线图
                i = -1
                for date in dates:
                    i = i + 1
                    if (date < calenda_data1 or date > calenda_data2):
                        df2 = df2.drop(i)
                    # print(df2)
                    # for element in df2.columns[1:]:
                dates = dates[dates >= calenda_data1]
                dates = dates[dates <= calenda_data2]
                for element in df2.columns[1:]:
                    if(element==option_info):
                     plt.plot(dates, df2[element], label=element)
            # 添加标题、标签和图例,精简x轴数据显示
            unique_x_values = list(set(dates))
            plt.xticks(unique_x_values)
            plt.rcParams['font.sans-serif'] = ['SimHei']  # 设置中文显示
            plt.rcParams['axes.unicode_minus'] = False  # 解决负号显示问题
            plt.title(option_info + '折线图', fontproperties='SimHei')
            plt.xlabel('日期', fontproperties='SimHei')
            plt.ylabel('元素值', fontproperties='SimHei')
            plt.legend(loc='upper right')
            # 格式化日期显示
            plt.gca().xaxis.set_major_formatter(plt.matplotlib.dates.DateFormatter('%Y-%m-%d'))
            # 自动调整日期标签的显示以防止重叠
            plt.gcf().autofmt_xdate()
            # 显示图形
            plt.show()
            NUM = NUM + 1
    else:print("日期输入错误")

#endregion

# 页面设计
#region My Code Block
df = "文件内的信息"
sof = "下拉栏中的信息"
root = tk.Tk()
root.title("导入Excel文件")
# 添加标签
label = tk.Label(root, text="请点击按钮选择Excel文件")
label.pack(pady=20)
# 添加导入按钮
import_button = tk.Button(root, text="导入Excel文件", command=import_button_click)
import_button.pack()
# 添加绘图按钮
# 显示一段时间
print_button = tk.Button(root, text="一段时间绘图", command=print_button_click)
print_button.pack(side=tk.LEFT, padx=5)
# 显示两天的对比
print_button2 = tk.Button(root, text="两天比较绘图", command=print_button2_click)
print_button2.pack(side=tk.LEFT, padx=5)
# 添加下拉框
# 创建下拉框选项
options = ["全元素", "元素1", "元素2", "元素3", "元素4", "元素5", "元素6", "元素7", "元素8", "元素9", "元素10"]
# 创建变量以存储选中的选项
selected_option = tk.StringVar(root)
selected_option.set(options[0])  # 设置默认选项
# 创建下拉框
option_menu = tk.OptionMenu(root, selected_option, *options)
option_menu.pack(pady=20)
# selected_option.trace_add("write", option_selected)
# 添加标签
label2 = tk.Label(root, text="左边为一段时间,右边为只看这两天")
label2.pack(pady=20)
# 创造日历选择
# 添加四个日期选择器到你的现有界面
root.date_entry1 = DateEntry(root, width=12, background='darkblue',
                             foreground='white', borderwidth=2)
root.date_entry1.pack(side=tk.LEFT, padx=10, pady=10)

root.date_entry2 = DateEntry(root, width=12, background='darkblue',
                             foreground='white', borderwidth=2)
root.date_entry2.pack(side=tk.LEFT, padx=10, pady=10)

root.date_entry3 = DateEntry(root, width=12, background='darkblue',
                             foreground='white', borderwidth=2)
root.date_entry3.pack(side=tk.LEFT, padx=10, pady=10)

root.date_entry4 = DateEntry(root, width=12, background='darkblue',
                             foreground='white', borderwidth=2)
root.date_entry4.pack(side=tk.LEFT, padx=10, pady=10)

# 启动主循环
root.mainloop()
#endregion
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
  • 123
  • 124
  • 125
  • 126
  • 127
  • 128
  • 129
  • 130
  • 131
  • 132
  • 133
  • 134
  • 135
  • 136
  • 137
  • 138
  • 139
  • 140
  • 141
  • 142
  • 143
  • 144
  • 145
  • 146
  • 147
  • 148
  • 149
  • 150
  • 151
  • 152
  • 153
  • 154
  • 155
  • 156
  • 157
  • 158
  • 159
  • 160
  • 161
  • 162
  • 163
  • 164
  • 165
  • 166
  • 167
  • 168
  • 169
  • 170
  • 171
  • 172
  • 173
  • 174
  • 175
  • 176
  • 177
  • 178
  • 179
  • 180
  • 181
  • 182
  • 183
  • 184
  • 185
  • 186
  • 187
  • 188
  • 189
  • 190
  • 191
  • 192
  • 193
  • 194
  • 195
  • 196
  • 197
  • 198
  • 199
  • 200

2.安装pyinstaller并运行打包

1.在pycharm的终端这里点击一下
在这里插入图片描述
2.在打开的终端页面输入以下代码下载pyinstaller
如果下载不了的话可以看看网上解决方法,我的是蛮顺利的。

在
代码如下(示例):

pip install pyinstaller
  • 1

3.输入你文件的路径,
路径可以在这里看到,直接复制就行。
在这里插入图片描述

还是在终端输入cd+空格+粘贴你刚才复制的路径
在这里插入图片描述
4.打包你用到的库和模板
库和模板可以在开头看见,虽然有些库和模板没有写在开头,但是我们后面可以补上去(就跟有人没票坐火车一样,先挤上去,等后面再补票),先把这些写在开头的打包掉(这是有票的乘客),代码形式:pyinstaller --hidden-import 库A–hidden-import --hidden-import 库B python文件名+.py,同样写在终端里。
在这里插入图片描述

我的代码如下:

pyinstaller --hidden-import pandas --hidden-import matplotlib --hidden-import tkinter --hidden-import tkcalendar --hidden-import openpyxl --hidden-import babel main.py
  • 1

这里我的两个库并没有在开头出现,但是我在代码中使用了,这里忘记了自己导入的库也不要害怕,先把开头的导进去,后面有补票的办法。
这一步成功的话会生成一个dist文件夹,里面是我们的exe文件,还有一个SPEC文件,它的用处就是我们用来补票的,这个我们后面的步骤再聊。
在这里插入图片描述
5.打包代码
pyinstaller -F -w+空格+python文件名+.py,在这个命令中,pyinstaller 是打包工具的名称,-F 表示生成单个可执行文件(打包为单个文件),-w 表示在运行时不显示控制台窗口(仅限 Windows 系统),而文件名则是你的 Python 脚本文件的名称,同样我们把指令写到终端里,代码如下

pyinstaller -F -w main.py
  • 1

在dist文件夹下(文件夹在你的python文件位置,忘了的话回步骤3看)我们就能找到生成的exe文件(应用程序),我们打开它
在这里插入图片描述

如果可以正常运行,那么恭喜你已经完成所有步骤,如果想在其他电脑上使用,只需要把exe文件(应用程序)这个东西复制粘贴到其他电脑中就行,如果出现如图所示的报错
在这里插入图片描述
是因为之前导入的库或模块不全导致了不能识别代码中的一部分(相当于没买票上车的人被乘务员发现了),那么请看接下来的报错处理部分(乖乖补票)。

6.报错处理
我们发现报错是因为缺少一个名字为’babel.numbers’的模块(这个坏同志没买票),我们现在来手动把它添加,回到之前的文件夹。请添加图片描述
我们用笔记本打开SPEC文件,这个文件就是乘务员让我们补票的地方。
在这里插入图片描述
找到标蓝的地方,把刚才警告中显示缺少的库或者模板添加进去,添加的格式如下:

   hiddenimports=['babel.numbers'],
  • 1

多项的话就这么写:

   hiddenimports=['U','S','T','B'],
  • 1

保存后关闭文本。
回到pycharm的终端,输入pyinstaller python文件名.spec
在这里插入图片描述
等待成功改写后,我们再次打开exe文件(应用程序),发现已经可以运行了(还不行的话看看还有没有落下的库,重复步骤6,不然我也无能为力了)
在这里插入图片描述
这时候我们就可以把exe文件复制出来发给别的电脑用了。
7.删除文件
如果删除dist文件夹和SPEC文件的话,对原来代码的运行是没有影响的,这只是我们打包时产生的输出,如果看着碍眼,打包成功后可以直接扔到垃圾桶里,在我们整个打包过程中也可以随时删除,反正每次打包的时候如果有这个文件夹就把旧的改了写在里面,没有的话系统会自动创建一个写在里面。

结尾

希望新的一年里北交和北科合并成,成为985大学,直接进行一个学历升值。
祝大家新年快乐,写的代码永远一次通过,永远没有BUG!!
在这里插入图片描述

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/羊村懒王/article/detail/647314
推荐阅读
相关标签
  

闽ICP备14008679号