I am trying to make a standalone mac app that will run on computers other than mine once people have the app file. Structure-wise, it is very simple. One python file has all of the tkinter
related stuff, and another handles the logic. There is also a json
file that the python files read from. I used pyinstaller
to bundle everything and got a .app file that ran perfectly well on my computer. However, on someone else's computer, they couldn't get to one particular page of the app. Since it worked on my computer, the error had to be coming from something that differed between our computers, so I assumed it was related to file paths. Furthermore, the view they couldn't see was the only view that involved writing to a file. Then I found out something strange. If you go into the contents of the app and run the main unix executable in terminal (which I did so I could get a text output describing the error), the app runs perfectly normally on their computer. Why does this work? What is making it fail as a .app file but work as a unix executable?
Here is my code for the button that goes to the failed view and the failed view
#Function called by button to load the view that failed
def check_answer(self, question, response):
self.answerView = AnswerView(self.container, self, question, response)
self.answerView.grid(row=0, column=0, sticky="nsew")
self.answerView.tkraise()
#AnswerView class
class AnswerView(tk.Frame):
def nextQ(self):
global questionNum
if questionNum == len(questions) - 1:
self.controller.quit_game()
else:
questionNum += 1
nextQ = questions[questionNum]
self.controller.view_question(nextQ)
def __init__(self, parent, controller, question: Question, response: str):
global resultsList
global correctNum
global done
if question is None or response is None:
Frame.__init__(self, parent)
self.controller = controller
pass
else:
Frame.__init__(self, parent)
self.controller = controller
if question.type == 'multiple_choice':
answer = question.realAnswer
else:
answer = question.answer
correct = question.check_answer(response)
resultsList += [{
"question": question.question,
"correctAns": answer,
"response": response,
"correct": correct,
"difficulty": question.difficulty,
"category": question.category
}]
userName = sys.argv[0].split('/')[2]
with open(f'/Users/{userName}/Downloads/{userName}TriviaResults.json', 'w') as results_file:
json.dump(resultsList, results_file, indent=0)
done += 1
if correct:
feedback = Label(self, text="RIGHTO!", fg='green').pack()
correctNum += 1
print(f"it's right! for the {correctNum}th time!")
else:
feedback = Label(self, text=f'INCORRECT, YOU FOOL! The correct answer was {answer}', fg='red').pack()
nextButton = Button(self, text="Next Question", command=self.nextQ).pack()
quitButton = Button(self, text="End Game", command=lambda: self.controller.quit_game()).pack()
#code to deal with file paths of stuff within the app
def resource_path(path: os.PathLike):
return os.path.join(os.path.dirname(sys.argv[0]), path)
Those are the only references to sys
in the code, and I figured the stuff in sys
would be different on different computers so that was a likely candidate.
I didn't want to burden you with a ton of code, but I am happy to provide more if you ask. I know there is a lot of info that could potentially be relevant here. Thanks!