由Pyinstaller exe生成的带有tkinter GUI的exe不起作用

时间:2019-07-26 11:12:23

标签: python tkinter exe pyinstaller

我使用Pyinstaller将Python脚本转换为独立的可执行程序。

我的脚本在spyder中进行测试时可以运行,但是作为exe不能运行,而且我也看不到为什么。

计划详情

我的程序由:

  • 一种具有一系列功能的处理。它以两个csv文件作为输入,并返回一个单行熊猫DataFrame。最后一个函数称为add_data()

  • 一个test()函数,该函数调用add_data(),将其结果保存在csv文件中,并在执行结束时通知用户

  • 具有{strong> try-except 条件的execute_test()函数; 尝试使用GUI中的用户输入调用test(),例外显示错误消息框。

  • 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 ,并且我之前没有在环境中安装它。我在收到此消息后就这样做了,但是并没有改变。

包括治疗的整个代码可能太长,但是我明确导入的内容是:熊猫 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合作,并尝试避免使用点子。我的环境的配置是:

  
      
  • Windows 10 / conda 4.7.10 / Python 3.7.3 / spyder 3.3.6
  •   
  • 熊猫 0.25.0 / 地理熊猫 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()

1 个答案:

答案 0 :(得分:0)

@ M.R。之后的建议,回答该问题的有用陈述是:

  • 警告可以忽略
  • 因为我在命令提示符中没有错误回溯,所以似乎阻止的不是我发布的代码,而是之前

我按功能检查了我的治疗功能的细节。似乎只有一个功能(至少)使整个事情不起作用。

这是一个调用geopandas和shape的对象,并且以前有关于pyproj的错误;如果我自己没有成功调试它,我可能会专门针对此问题打开一个新问题(与我在此处提出的问题相同:就目前而言,我的python脚本可以正常工作,而我看不到为什么将其作为exe突然没有)。在这种情况下,我将在此处链接下一个问题。

如果它可以帮助其他绝望的程序员,那么在调试过程中对我也有帮助的是:

  • 我的功能已经被分离(这使得生成单独的exe更加容易)

  • 使用最小的GUI将每个功能转换为exe很有用。如果有人遇到暗示用户输入的类似问题,请在节省时间的情况下随意使用我作为布局发布的GUI代码。您只需要在开始时添加函数,然后在test()部分(我称之为add_data()的部分)中更改调用的内容即可。

  • 我还遵循了How to debug small programs provides tips的建议。花了一些时间,但是值得。