Pyinstaller - “致命错误!将脚本转换为 exe 时无法执行脚本”
Posted
技术标签:
【中文标题】Pyinstaller - “致命错误!将脚本转换为 exe 时无法执行脚本”【英文标题】:Pyinstaller - “Fatal error ! Failed to execute script” when converting script to exe 【发布时间】:2021-07-17 06:50:20 【问题描述】:我有一个用 tkinter 构建的 GUI,它通过从 excel 文件中读取链接来进行网络抓取,然后将所有结果存储在 excel 文件中。此外,它还有一些按钮,允许从 excel 文件中绘制数据,做一些简单的过滤器。我在 Pycharm 中正确构建了它。现在,我需要构建一个 exe 文件,为此我使用 pyinstaller 和此代码 pyinstaller.exe --onefile --windowed main.py
。问题是它给出了一个致命错误并且无法执行脚本。我已经尝试在我的环境中安装 cmd 中的所有软件包,但错误仍然存在。
这里我放了我的 main.py(这里是 link 到 github,functions.py 和输入数据在哪里):
from tkinter import messagebox
from PIL import Image, ImageTk
from tkinter.filedialog import askopenfile
from functions import *
import os
import threading
excel_QS_resultados = os.path.dirname(__file__) + "/Resultados_QS"
excel_ponderacion_name = os.path.dirname(__file__) + "/Ponderación_Metologías"
def open_file():
browse_text.set("Ejecutando...")
file = askopenfile(parent = root, mode = "rb", title = "Elija un archivo", filetype = [("Excel file", "*.xlsx")])
if file:
if not os.path.exists(os.path.dirname(__file__) + "/Tablas"):
os.mkdir(os.path.dirname(__file__) + "/Tablas")
#print(os.getcwd())
guardar_tablas(file.name[:-5], os.path.dirname(__file__) + "/Tablas",
excel_QS_resultados, root)
browse_text.set("Cargar tablas de las webs de rankings")
def to_plot(kind, latam = False):
file = askopenfile(parent=root, mode="rb", title="Elija un archivo", filetype=[("Excel file", "*.xlsx")])
if file:
if "QS" in os.path.basename(os.path.normpath(file.name[:-5])):
ranking_name = "QS"
subjects_QS = 0: os.path.basename(os.path.normpath(file.name[:-5]))[3:]
subjects_THE =
else:
ranking_name = "THE"
subjects_THE = 0: os.path.basename(os.path.normpath(file.name[:-5]))[4:]
subjects_QS =
df_subject = pd.read_excel(file.name)
if ranking_name == "QS":
list_years, list_years_2 = Get_If_UniRanked(df_subject, ranking_name, excel_QS_resultados, subjects_QS,
0) # También imprime años rankeados
list_years_rank = ["La PUCP fue rankeada en el año " + str(year) for year in list_years]
list_years_result = ["Se tienen los resultados de la PUCP en el año " + str(year) for year in list_years_2]
if list_years_rank == []:
list_years_rank.append("La PUCP no fue rankeada en ninguno de los años")
if list_years_result == []:
list_years_result.append("No se tienen resultados de la PUCP en ninguno de los años")
top = Toplevel(root)
canvas2 = Canvas(top, width=600, height=300)
canvas2.pack()
header = Frame(canvas2, width=500, height=200, bg = "#14a4d6")
header.grid(columnspan=5, rowspan=2, row=0)
header1 = Frame(canvas2, width=500, height=15, bg = "#14a4d6")
header1.grid(columnspan=3, rowspan=1, row=1)
main_content = Frame(canvas2, width=500, height=100, bg="#14a4d6")
main_content.grid(columnspan=5, row=2)
display_text_box("\n".join(map(str, list_years_rank + list_years_result)), 0, 1, canvas2)
instructions = Label(header1, text="Seleccione el año ",font="Raleway")
instructions.grid(column=1, row=2)
for i in range(len(list_years)):
button = Button(main_content, text=list_years[i], font=("shanti", 10), height = 1, width = 6)
button.grid(column=i, row=1, padx = 15, pady = 15)
else:
list_years = Get_If_UniRanked(df_subject, ranking_name, excel_QS_resultados, subjects_THE, 0)
list_years_rank = ["La PUCP fue rankeada en el año " + str(year) for year in list_years]
if list_years_rank == []:
list_years_rank.append("La PUCP no fue rankeada en ninguno de los años")
top = Toplevel(root)
canvas2 = Canvas(top, width=600, height=300)
canvas2.pack()
header = Frame(canvas2, width=500, height=200, bg="#14a4d6")
header.grid(columnspan=5, rowspan=2, row=0)
header1 = Frame(canvas2, width=500, height=15, bg="#14a4d6")
header1.grid(columnspan=3, rowspan=1, row=1)
main_content = Frame(canvas2, width=500, height=100, bg="#14a4d6")
main_content.grid(columnspan=5, row=2)
display_text_box("\n".join(map(str, list_years_rank )), 0, 1, canvas2)
instructions = Label(header1, text="Seleccione el año ", font="Raleway")
instructions.grid(column=1, row=2)
if kind ==3:
list_years = list_years_2[::-1]
for i in range(len(list_years)):
button = Button(main_content, text=list_years[i], font=("shanti", 10), height=1, width=6,
command =lambda i=i: plot(file, ranking_name, subjects_THE, subjects_QS, str(list_years[i]), kind, latam))
button.grid(column=i, row=1, padx=15, pady=15)
def plot(file, ranking_name, subjects_THE, subjects_QS, year, kind, latam):
df_subject = pd.read_excel(file.name)
df_with_method = apply_methodology_continent(df_subject, excel_ponderacion_name, ranking_name, 0,
subjects_THE, subjects_QS).copy()
time = datetime.datetime.now().time().strftime("%H-%M-%S")
if ranking_name == "QS":
df_with_method.to_excel(os.path.dirname(__file__) + "/" + ranking_name + " " + subjects_QS[0] + " " + time + ".xlsx",
index=False)
elif ranking_name == "THE":
df_with_method.to_excel(os.path.dirname(__file__) + "/" + ranking_name + " " + subjects_THE[0] + " " + time + ".xlsx",
index=False)
else:
pass # datetime.datetime.now().time().strftime("%H:%M:%S")
if kind == 1:
df_6Higher_Uni = Get_6Higher_Uni(df_with_method, int(year), ranking_name, latam)
if df_6Higher_Uni is not None:
Plot_6Higher_Uni(df_6Higher_Uni, ranking_name, latam)
Plot_6HigherUni_Contribution(df_6Higher_Uni, excel_ponderacion_name, subjects_QS,
subjects_THE, 0, ranking_name, latam)
else:
messagebox.showwarning("Advertencia",
"Existen datos incompletos en el mismo rango de puestos que la PUCP. Analice un año anterior.")
elif kind == 2:
df_6Bottom_Uni = Get_6Bottom_Uni(df_with_method, int(year), ranking_name, latam)
if df_6Bottom_Uni is not None:
Plot_6Higher_Uni(df_6Bottom_Uni, ranking_name, latam)
Plot_6HigherUni_Contribution(df_6Bottom_Uni, excel_ponderacion_name, subjects_QS,
subjects_THE, 0, ranking_name, latam)
else:
messagebox.showwarning("Advertencia",
"Existen datos incompletos en el mismo rango de puestos que la PUCP. Analice un año anterior.")
else:
df_6Bottom_Uni = Get_6Bottom_Uni_QS_Result(df_with_method, int(year), excel_ponderacion_name,
excel_QS_resultados, 0, subjects_QS, latam)
if df_6Bottom_Uni is not None:
Plot_6Higher_Uni(df_6Bottom_Uni, ranking_name, latam)
Plot_6HigherUni_Contribution(df_6Bottom_Uni, excel_ponderacion_name, subjects_QS,
subjects_THE, 0, ranking_name, latam)
else:
messagebox.showwarning("Advertencia",
"Existen datos incompletos en el mismo rango de puestos que la PUCP. Analice un año anterior.")
root = Tk()
root.iconbitmap("C:/Users/Franco/PycharmProjects/THE_QS/icon.ico")
root.title("Generador de gráficos- Rankings THE y QS by Subject")
header = Frame(root, width=800, height=150)
header.grid(columnspan=3, rowspan=2, row=0)
main_content = Frame(root, width=800, height=150, bg="#14a4d6")
main_content.grid(columnspan=3, rowspan=4, row=4)
btn_options = ["R - Siguientes 6 Univ. Rankeadas Global",
"R - Siguientes 6 Univ. Rankeadas LATAM",
"NR/R - Últimas 6 Universidades Rankeadas Global",
"NR/R - Últimas 6 Universidades Rankeadas LATAM",
"NR - QS Últimas Universidades Rankeadas Global",
"NR - QS Últimas Universidades Rankeadas LATAM"]
next6Global_btn = Button(root, text = btn_options[0], font=("shanti", 10), height = 1, width = 40, command = lambda: to_plot(kind = 1))
next6Latam_btn = Button(root, text = btn_options[1], font=("shanti", 10), height = 1, width = 40, command = lambda: to_plot(kind = 1, latam=True))
last6Global_btn = Button(root, text = btn_options[2], font=("shanti", 10), height = 1, width = 40, command = lambda: to_plot(kind = 2))
last6Latam_btn = Button(root, text = btn_options[3], font=("shanti", 10), height = 1, width = 40, command = lambda: to_plot(kind = 2, latam=True))
QSlast6Global_btn = Button(root, text = btn_options[4], font=("shanti", 10), height = 1, width = 40, command = lambda: to_plot(kind = 3))
QSlast6Latam_btn = Button(root, text = btn_options[5], font=("shanti", 10), height = 1, width = 40, command = lambda: to_plot(kind = 3, latam=True))
next6Global_btn.grid(row = 4, column = 1)
next6Latam_btn.grid(row = 4, column = 2)
last6Global_btn.grid(row = 5, column = 1)
last6Latam_btn.grid(row = 5, column = 2)
QSlast6Global_btn.grid(row = 6, column = 1)
QSlast6Latam_btn.grid(row = 6, column = 2)
# logo
display_logo("C:/Users/Franco/PycharmProjects/THE_QS/pucp-logo.png", 0, 1)
# instructions
instructions = Label(root, text="Seleccione el archivo excel con los enlaces de los rankings by subject", font="Raleway")
instructions.grid(columnspan=4, rowspan= 3, column=1, row=1)
# browse
browse_text = StringVar()
browse_text.set("Cargar tablas de las webs de rankings")
browse_btn = Button(root, textvariable = browse_text, font="Raleway", bg="#14a4d6",
command = lambda: threading.Thread(target=open_file).start(), fg="white", height=2, width=35)
browse_btn.grid(columnspan = 3, column=1, row=2)
root.mainloop()
我非常感谢您对此提供的帮助,因为我已经尝试了一段时间但没有成功。
更新
在几个月没有完成这个项目之后,我想证明我从你那里得到的一些新建议。
我尝试了@Blueman7 关于缺少icon=part
的建议,我在 cmd 中使用的命令如下(以防我在执行时出错,因为它仍然不起作用但有一些改进):
执行此命令后,我得到了一个带有 icon.ico 的 main.exe。当我尝试运行此 .exe 时,它会打开一个黑色窗口并保持大约 1 分钟,此时它在与 pyzmq 包相关的图像中出现错误。
我尝试将此文件夹 pyzmq.libs 复制到我当前的项目路径并在 cmd 中运行命令pyinstaller.exe --onefile --icon=icon.ico --add-data "./pyzmq.libs;." main.py
。另外,我尝试将 pyzmq 导入我的 conda 环境,但到目前为止它都不起作用。
非常感谢您的建议。
【问题讨论】:
【参考方案1】:在您的代码中,您忘记提及 icon=part。
pyinstaller.exe --onefile --windowed --icon=yourico.ico main.py
【讨论】:
谢谢,它帮助了我,但现在它给我带来了一个新错误(我已经在我的帖子中更新了这个。)【参考方案2】:对我有用的只是:
pyinstaller --onefile main.py
没有 -windowed 或 -w
【讨论】:
【参考方案3】:提供您获得的错误的屏幕截图始终有助于理解您的问题。
但是根据您提供的信息,我认为您的问题出在您正在使用的命令上,应该是,
pyinstaller --onefile --windowed main.py
有关如何使用 pyinstaller 创建可执行文件的详细信息,请查看 -> https://datatofish.com/executable-pyinstaller/
如果这不起作用,请尝试使用py2exe
看看这个,
https://stackabuse.com/creating-executable-files-from-python-scripts-with-py2exe
【讨论】:
你能提供你得到的错误吗! 如果 pyinstaller 不起作用,请尝试使用 py2exe 或其他此类软件包。【参考方案4】:试试:
pyinstaller onefile -w main.py
这行得通吗?
【讨论】:
以上是关于Pyinstaller - “致命错误!将脚本转换为 exe 时无法执行脚本”的主要内容,如果未能解决你的问题,请参考以下文章