【发布时间】:2019-12-04 17:32:32
【问题描述】:
我使用 Pyinstaller 将我的 Python 脚本变成了一个独立的可执行程序。
当我在 spyder 中测试时,我的脚本可以运行,但作为 exe 却不能,我不明白为什么。
节目详情
我的程序由:
由一系列函数组成的处理。它将两个 csv 文件作为输入并返回一个单行 pandas DataFrame。最后一个函数叫做
add_data()调用 add_data() 的
test()函数,将其结果保存在 csv 文件中,并在执行结束时通知用户一个带有 try-except 条件的
execute_test()函数; try 使用来自 GUI 的用户输入调用 test(),except 显示错误消息框。一个 tkinter GUI 要求用户选择两个 csv 文件 + 一个 test() 将保存 csv 结果的目录。
行为
在 spyder 上,执行 python 脚本时,我选择文件和目录,它返回“处理完成”消息框,所以问题不应该来自脚本本身。
Pyinstaller 成功构建 exe 文件。我可以打开它,出现 GUI 和命令提示符;条目和按钮工作正常。
选择相同的文件和目录后启动处理时,只返回错误信息框,表示处理由于某种原因没有执行。 我从提示中得到的唯一消息是这条消息:
C:\Users...\Continuum\miniconda3\envs\myenv\lib\site-packages\PyInstaller\loader\pyimod03_importers.py:627: MatplotlibDeprecationWarning:MATPLOTLIBDATA 环境变量 在 Matplotlib 3.1 中已弃用,将在 3.3 中删除。
我没有在我的程序中显式导入matplotlib,而且我之前也没有在我的环境中安装它。我在这条消息之后做了,但它没有任何改变。
包含我处理的整个代码会太长,但我在其中明确导入的是:pandas、geopandas、shapely.geometry、tkinter(参见下面的代码)。由于我之前遇到过问题(已解决),因此在使用 geopandas 时似乎也需要 pyproj
Pyinstaller 信息
如果需要,我可以提供将脚本转换为 .exe 时得到的全部提示输出。 值得一提的是我得到了:
一些不包括进口关于PySide、PyQt5、gtk、matplotlib、PyQt4、tkinter
此警告:
71826 WARNING: Hidden import "PyQt5.sip" not found!并且警告说它没有找到某些 DLL:
81853 INFO: Looking for dynamic libraries
81931 WARNING: lib not found: tbb.dll dependency of ...\mkl_tbb_thread.dll
81978 WARNING: lib not found: msmpi.dll dependency of C:\Users\...\bin\mkl_blacs_msmpi_lp64.dll
82509 WARNING: lib not found: pgf90rtl.dll dependency of C:\Users\...\bin\mkl_pgi_thread.dll
82525 WARNING: lib not found: pgc14.dll dependency of C:\Users\...\bin\mkl_pgi_thread.dll
82556 WARNING: lib not found: pgf90.dll dependency of C:\Users\...\bin\mkl_pgi_thread.dll
82587 WARNING: lib not found: msmpi.dll dependency of C:\Users\...\bin\mkl_blacs_msmpi_ilp64.dll
82634 WARNING: lib not found: mpich2mpi.dll dependency of C:\Users\...\bin\mkl_blacs_mpich2_lp64.dll
82712 WARNING: lib not found: mpich2mpi.dll dependency of C:\Users\...\bin\mkl_blacs_mpich2_ilp64.dll
82869 WARNING: lib not found: impi.dll dependency of C:\Users\...\bin\mkl_blacs_intelmpi_lp64.dll
83025 WARNING: lib not found: impi.dll dependency of C:\Users\...\bin\mkl_blacs_intelmpi_ilp64.dll
配置
我使用 Miniconda 并尽量避免使用 pip。我的环境配置是:
- Windows 10 / conda 4.7.10 / Python 3.7.3 / spyder 3.3.6
- 熊猫 0.25.0 / geopandas 0.5.1 / pyproj 2.2.1 / tk 8.6.9
- numpy 1.16.4 / matplotlib 3.1.1
- pyinstaller 3.5 / setuptools 41.0.1 / pywin32 224
还有很多我不知道的其他包和模块(虽然不是 anaconda)。
我什至不知道确切的标题是什么,因为我不知道错误来自 哪里(我的猜测是 tkinter、matplotlib 或者可能是 numpy)。
我还想说我是一个初学者程序员,我在处理整个包/模块/导入/依赖项/DLL/兼容性方面的问题。仍在研究它,我大致了解大多数概念,但我可能需要详细解释此级别发生的事情以便调试它。 有人可以帮忙吗?
我的代码
from tkinter import Tk, Frame, Label, Button, Entry,\
filedialog as fd, messagebox
## Functions that will be called by user interaction with the GUI
def test(file_L, file_T, directory):
df_test = add_data(file_L, file_T) # calls the previous treatment
path=str(directory)+'/'+'test_result.csv'
df_test.to_csv(path, encoding='utf-8', index=False)
messagebox.showinfo("End", "The treatment is done")
def execute_test(inputL, inputT, inputD):
try:
return test(inputL.filedir.get(),
inputT.filedir.get(),
inputD.selecdir.get())
except:
messagebox.showerror("Error", "The program failed to launch.\n"\
"Either the inputs are not correct, or an "\
"intern error occured.")
# Class Button + Entry to select a csv file
class Selection:
def __init__(self, master):
self.filedir = Entry(master, bd=2)
self.load_button = Button(master, text="...", bg='yellow',
command=self.loadFile)
def loadFile(self):
self.filename = fd.askopenfilename(
filetypes = (("csv files","*.csv"),("all files","*.*"))
)
self.filedir.delete(0,"end")
self.filedir.insert(0, self.filename)
# Class Button + Entry to select a directory
class Directory:
def __init__(self, master):
self.selecdir = Entry(master, bd=2)
self.load_button = Button(master, text="...", bg='yellow',
command=self.loadDir)
def loadDir(self):
self.dirname = fd.askdirectory()
self.selecdir.delete(0,"end")
self.selecdir.insert(0, self.dirname)
# GUI itself
if __name__=='__main__':
from functools import partial
#-----Defining the root
root = Tk()
root.geometry("+800+400")
#-----Defining the Frames
f2 = Frame(root)
f2.grid_columnconfigure(0, weight=2)
f2.grid_columnconfigure(1, weight=1)
f2.grid_rowconfigure(0, weight=1)
f2.grid_rowconfigure(1, weight=1)
f2.grid_rowconfigure(2, weight=1)
f2.grid_rowconfigure(3, weight=1)
f2.grid_rowconfigure(4, weight=1)
f2.grid_rowconfigure(5, weight=1)
f3 = Frame(root)
#-----Defining the widgets
TextL = Label(f2, text="Please select file L :")
L = Selection(f2)
TextT = Label(f2, text="Please select file T :")
T = Selection(f2)
TextD = Label(f2, text="Please select the directory in which the result "\
"will be saved as a csv :")
D = Directory(f2)
b_validate = Button(f3, text="Execute", bg='cyan',
command = partial(execute_test, L, T, D))
b_exit = Button(f3, text="Exit", bg='red', command = root.destroy)
#-----Geometry managers
f2.pack(expand=True)
f3.pack(side='right')
TextL.grid(row=0)
L.filedir.grid(row=1, column=0, sticky='ew')
L.load_button.grid(row=1, column=1, sticky='w')
TextT.grid(row=2)
T.filedir.grid(row=3, column=0, sticky='ew')
T.load_button.grid(row=3, column=1, sticky='w')
TextD.grid(row=4)
D.selecdir.grid(row=5, column=0, sticky='ew')
D.load_button.grid(row=5, column=1, sticky='w')
b_validate.pack(side='left')
b_exit.pack(side='left')
root.mainloop()
【问题讨论】:
-
更新:我做了一个模拟的“add_data()”函数来提供一个功能性的GUI来指出错误;它只是连接两个输入 csv 文件的列并返回连接的数据帧。它有效......所以问题似乎来自“处理”部分和pyinstaller之间的不兼容。我将按功能探索这个主要功能,如果我取得一些进展,我会更新这个问题。
-
我在你的问题中看不到错误,所有这些都是警告,可以忽略。此外,您的代码不会导入
pandas。使用 CMD 运行您的可执行文件并放置完整的错误回溯。 -
好的,关于警告。当我需要它时,我在函数中导入了熊猫。我通过 CMD 运行它,但没有得到错误回溯;我得到的只是我最初发布的相同 Matplotlib 警告。错误消息只是我编程的 showerror 消息框,所以它“只是”我的程序没有运行(我现在正在逐个函数调查)
标签: python tkinter exe pyinstaller