[Python] Pyinstaller "returned -1"

Discussão em 'Python' iniciado por Stack, Setembro 27, 2024.

  1. Stack

    Stack Membro Participativo

    I know this question has been asked many times before, but after browsing the answers, I cannot seem to figure out what is going wrong.

    I have a python script (below) and I am trying to use Pyinstaller to make it into an executable file (I am on windows).

    When I am in the directory of my Plot.py file, I type into the command prompt:

    pyinstaller.exe --onefile --windowed Plot.py


    It then successfully creates the exe file, but when I attempt to open it, a window pops up titled "Fatal Error!" that says "Plot returned -1".

    I have made executables before using Pyinstaller from python scripts using Tkinter and tkFileDialog. From what I have researched, Pyinstaller supports matplotlib.

    Any ideas what is going wrong?

    Plot.py is below:

    '''
    Plot.py
    Opens a GUI and allows users to select text files with five columns: x, y, z, t, e
    Then, it makes two graphs and shows them - x vs y vs z and e vs t
    '''

    from mpl_toolkits.mplot3d import Axes3D
    import matplotlib.pyplot as plt
    import tkFileDialog
    from Tkinter import *

    def get_name_from_file(path):
    '''
    takes a path and returns just the name of the file
    i.e. C:/Users/joe.iosue/Documents/helloworld.txt returns helloworld.txt
    '''
    while path.count("/") > 0:
    i = path.index("/")
    path = path[i+1:]
    return path

    def make_plot(x, y, z, title):
    '''
    returns a plt object that can be saved to show later
    x, y, z are lists of floats, but the 0th index is a string: the title of that axes.
    title is a string
    '''
    fig = plt.figure()
    #If there is no z list, the graph should only be 2d (energy vs time)
    if z != None:
    plot = fig.add_subplot(111, projection='3d')
    plot.set_zlabel(z[0])
    plot.scatter(x[1:], y[1:], z[1:], c='r', marker='o')
    plot.set_xlabel(x[0])
    plot.set_ylabel(y[0])
    plot.set_zlabel(z[0])
    else:
    plt.plot(x[1:], y[1:], c='r', marker='o')
    plt.xlabel(x[0])
    plt.ylabel(y[0])
    plt.title(title)
    return plt

    class Graph(object):
    '''
    Reads from a file that has 5 columns: x, y, z, t, KE
    There are two graphs: a position graph (x, y, z)
    and a Kinetic energy vs Time graph (t, KE)
    '''
    def __init__(self, filename, xlabel='X', ylabel='Y', zlabel='Z', tlabel='t', elabel='KE', title='Title'):
    self.title = title
    f = open(filename, 'r')
    data = f.readlines()
    f.close()
    #first index of the lists are what I am going to name the axes
    self.xList, self.yList, self.zList, self.tList, self.eList = [xlabel], [ylabel], [zlabel], [tlabel], [elabel]
    lines = []
    for element in data:
    lines.append(element.split())
    for element in lines:
    #In case I decide later to add comments in my text file with the points
    #I added this try statement so it won't add a comment to the point lists
    try:
    self.xList.append(float(element[0]))
    self.yList.append(float(element[1]))
    self.zList.append(float(element[2]))
    self.tList.append(float(element[3]))
    self.eList.append(float(element[4]))
    except:
    pass
    def plot_position(self):
    make_plot(self.xList, self.yList, self.zList, self.title).show()
    def plot_energy(self):
    make_plot(self.tList, self.eList, None, self.title).show()
    def plot_both(self):
    '''
    matplotlib works in global frame, so this makes both plots
    (x vs y vx z and ke vs t) in global frame and then shows both
    at the same time
    '''
    make_plot(self.xList, self.yList, self.zList, self.title)
    make_plot(self.tList, self.eList, None, self.title).show()

    class OpenDialogMenu(object):
    '''
    opens file menu only allowing text files to be chosen
    '''
    def __init__(self, master):
    self.master = master
    self.file_options = options = {}
    options['defaultextension'] = '.txt'
    options['filetypes'] = [('TXT files', '.txt')]
    options['initialdir'] = 'C:\Documents'
    options['parent'] = self.master
    options['title'] = 'Open File Menu'
    self.filename = tkFileDialog.askopenfile(mode="r", **self.file_options)
    def get_filename(self):
    '''
    If user opens file menu and then closes it without picking
    a file, should return None
    '''
    try:
    return self.filename.name
    except:
    return None

    class Home(object):
    '''
    master is a Tk window
    Home can store multiple text files ready to plot
    '''
    def __init__(self, master):
    self.master = master
    self.master.title('Plot')
    # In case the icon file is not in the correct directory
    try:
    self.master.wm_iconbitmap("ploticon.ico")
    except:
    pass
    self.open= Button(self.master, text='Open', command=self.Open, width=10)
    self.plot = Button(self.master, text='Plot', command=self.Plot, width=10)
    self.plot.grid(row=0, column=0)
    self.open.grid(row=0, column=1)
    self.row = 1
    self.files, self.labels = [], []

    self.menubar = Menu(self.master)
    self.filemenu = Menu(self.menubar, tearoff=0)
    self.menubar.add_cascade(label="File", menu=self.filemenu)
    self.filemenu.add_command(label="New", command=self.New)
    self.filemenu.add_command(label="Open", command=self.Open)
    self.filemenu.add_command(label="Reset", command=self.delete_files)
    self.filemenu.add_separator()
    self.filemenu.add_command(label="Exit", command=self.master.destroy)
    self.master.config(menu=self.menubar)

    self.master.bind('<Control-o>', self.Open)
    self.master.bind('<Return>', self.Plot)
    self.master.bind('<Control-n>', self.New)
    self.master.bind('<Control-r>', self.delete_files)

    def Open(self, callback=False):
    '''
    opens the open dialog menu and adds the chosen file to self.files
    and adds a label to the window with name of file
    '''
    f = OpenDialogMenu(self.master)
    self.filename = f.get_filename()
    if self.filename != None:
    name = get_name_from_file(self.filename)
    self.labels.append(Label(self.master, text=name))
    self.labels[len(self.labels)-1].grid(row=self.row, columnspan=50)
    self.row+=1
    self.files.append(Graph(filename=self.filename, title=name))

    def Plot(self, callback=False):
    '''
    plots plt objects
    '''
    for element in self.files:
    element.plot_both()

    def New(self, callback=False):
    '''
    opens new tkinter window with Home attributes
    '''
    root = Tk()
    Home(root)
    root.mainloop()

    def delete_files(self, callback=False):
    '''
    removes all files from file and label list
    '''
    for element in self.labels:
    element.destroy()
    self.labels = []
    self.files = []

    if __name__ == '__main__':
    root = Tk()
    Home(root)
    root.mainloop()


    I should mention, the py file works.

    I know the code is a bit contrived, but it works exactly how I want it to work for what I need it to do.

    Continue reading...

Compartilhe esta Página