0

I want to make a standalone executable out of a script on a MacOS (10.14).

The script is my_app.py and has the following content:

#!/usr/bin/env python

import os.path
import csv
import pandas as pd

##1 open the file
f=open("path/to/original_file.txt", "r")

filedata = f.read()
##1

##1.1 replace the desired characters
filedata = filedata.replace("\\", ",")
filedata = filedata.replace("*", "")

with open("path/to/new_file.txt", 'w') as file:
  file.write(filedata)
##1.1

and the following setup.py file:

from setuptools import setup

APP = ["my_app.py"]
DATA_FILES = []
OPTIONS = {
    "argv_emulation": True,
    "packages": ["certifi"],
}
setup(
    app = APP,
    data_files = DATA_FILES,
    options = {"py2app": OPTIONS},
    setup_requires = ["py2app"]

)

Following the steps in a previous SO questions with answer, I entered sequentially the following commmands in Terminal:

pip install virtualenv
virtualenv venv --system-site-packages
source venv/bin/activate
pip3.7 install -U py2app
cd /path/to/my_app.py
python setup.py py2app -A

However when I double click on my_app.app (which have just been created and which is located in /Users/mymac/Documents/applications/myapp/dist) I get the following error message in a pop-up window

enter image description here

What am I doing wrong? Does it have to do with the fact that there is no GUI framework in my app (like PyQT or Tkinter)?

ecjb
  • 5,169
  • 12
  • 43
  • 79

2 Answers2

0

Mist likely you need to include a runtime library of some sort but another option is to create a script to run your app and then fix so that you can start your script from the Finder by double clicking it, see this question for some alternative ways to do it.

The easiest way mentioned in the linked question is to give the script the extension .command then you shouldn’t need to do anything else.

The advantage of using a script is that it’s executed in the Terminal (in a shell) so you should have all the libraries etc available automatically.

Joakim Danielson
  • 43,251
  • 5
  • 22
  • 52
  • Thanks for your answer @JoakimDanielson. I tried that solution before. If I'm not mistaken, this implies that you have a Python version installed on the machine you are running. I would like to make the app running on a computer without having to have Python installed (standalone) – ecjb Feb 24 '19 at 08:30
  • @ecjb, Ah ok then you need to make sure you include the runtime and everything else in your app container. Unfortunately I can't help with that. Maybe something useful in [this question](https://stackoverflow.com/questions/5458048/how-to-make-a-python-script-standalone-executable-to-run-without-any-dependency) – Joakim Danielson Feb 24 '19 at 08:33
  • Thank you for the comment. I did check your link. `PyInstaller` seems to be a good alternative. I'm working on it and still have issues. I might post another question. What do you mean exactly by "runtime and everyting else": do you mean building the app around tkinter or PyQT? – ecjb Feb 24 '19 at 09:24
  • I just meant anything that is needed by your app to run on its own. Sorry I am not a Phyton guy, I just happened to see this and thought about running as a script as a possible solution – Joakim Danielson Feb 24 '19 at 09:26
0

I could finally build a standalone by

  • wrapping the application around a PyQt framework
  • use PyInstaller to build the app

The my_app.py should look like this:

import sys
from PyQt5 import QtCore, QtWidgets
from PyQt5.QtWidgets import QMainWindow, QLabel, QGridLayout, QWidget
from PyQt5.QtCore import QSize

class HelloWindow(QMainWindow):
    def __init__(self):
        QMainWindow.__init__(self)

        self.setMinimumSize(QSize(640, 480))
        self.setWindowTitle("Hello world")

        centralWidget = QWidget(self)
        self.setCentralWidget(centralWidget)

        gridLayout = QGridLayout(self)
        centralWidget.setLayout(gridLayout)

        title = QLabel("Hello World from PyQt", self)
        title.setAlignment(QtCore.Qt.AlignCenter)
        gridLayout.addWidget(title, 0, 0)

if __name__ == "__main__":
    app = QtWidgets.QApplication(sys.argv)
    mainWin = HelloWindow()
    mainWin.show()
    sys.exit( app.exec_() )

Then you cd the directory where the my_app.py resides. You then then run

PyInstaller my_app.py

This will create several directories: __pycache__, build and dist. Inside the dist there is another directory named my_app. In this directory there will be an executable named my_app (or referring to the original question, inside the path path/to/dist/my_app/) ==> double click on it and your app is running!

ecjb
  • 5,169
  • 12
  • 43
  • 79