2

It's a very straightforward and broad question I know but I have very little time so I have to ask. I created an interface to do some GIS calculations and for that I used below libraries in backend.

import osmnx as ox, networkx as nx, geopandas as gpd, pandas as pd
from shapely.geometry import LineString, Point
from fiona.crs import from_epsg
import branca.colormap as cm
import folium
from folium.plugins import MarkerCluster
import pysal as ps

and these for frontend

import tkinter as tk
from tkinter import ttk
from tkinter.filedialog import askopenfilename, asksaveasfilename, 
askdirectory
import backend as bk

I'm trying to make it an executable program and I've tried PyInstaller but it did not work because of the dependencies. Is there any way to do it with PyInstaller? or any other libraries? Or what should I do?

p.s : I'm using python 3.6

2nd EDIT:

I tried cx_freeze and created a setup.py and build it. After that, when I double click on the program It simply does nothing. No error messages, anything. My code is in below:

import cx_Freeze
import sys
import os 

PYTHON_INSTALL_DIR = os.path.dirname(sys.executable)
os.environ['TCL_LIBRARY'] = os.path.join(PYTHON_INSTALL_DIR, 'tcl', 'tcl8.6')
os.environ['TK_LIBRARY'] = os.path.join(PYTHON_INSTALL_DIR, 'tcl', 'tk8.6')

include_files = [(os.path.join(PYTHON_INSTALL_DIR, 'DLLs', 'tk86t.dll'), os.path.join('lib', 'tk86t.dll')),
                 (os.path.join(PYTHON_INSTALL_DIR, 'DLLs', 'tcl86t.dll'), os.path.join('lib', 'tcl86t.dll'))]

packages = ["pandas", "numpy", "tkinter", "matplotlib", "osmnx", "networkx",
            "geopandas", "shapely", "fiona", "branca", "folium",
            "pysal"]

base = None
if sys.platform == "win32":
    base = "Win32GUI"

executables = [cx_Freeze.Executable("frontend.py", base=base, icon="transport.ico")]

cx_Freeze.setup(
        name = "Network_Analyst",
        options = {"build_exe": {"packages":packages,
                                 "include_files":include_files}},
        version = "0.01",
        description = "Network analyst",
        executables = executables
        )

My program consists of two scripts which are frontend and backend. I'm importing backend on the frontend section, should I add it somewhere in the setup code? And one more thing, I'm working on an environment to do these processes, Is this has an effect on building a setup?

I'm giving a sample from my code to make your understanding better:

In frontend part I'm calling backend as

import backend as bk

and in the script:

class Centrality(tk.Frame):

    def degree_cent(self):
        print("Calculating Degree Centrality")
        G = self.findG()
        try:
            bk.degree_cent(G, self.t3.get("1.0",'end-1c'), self.t2.get("1.0",'end-1c'))
        except:
            bk.degree_cent(G, self.t3.get("1.0",'end-1c'))

In backend I don't use OOP, I just write the functions such as:

import osmnx as ox, networkx as nx, geopandas as gpd, pandas as pd

def degree_cent(G, outpath, *args):

    G_proj = ox.project_graph(G)    
    nodes, edges = ox.graph_to_gdfs(G_proj)
    nodes["x"] = nodes["x"].astype(float)

    degree_centrality = nx.degree_centrality(G_proj)
    degree = gpd.GeoDataFrame(pd.Series(degree_centrality), columns=["degree"])

Executable program still doesn't respond when I'm clicking on it. No respond at all. No any windows event (I've checked it from Windows Event Viewer).

omrakn
  • 45
  • 1
  • 9
  • I also have the same problem and it seems like it is a problem with packaging fiona. If you run your resulting EXE from the CMD line it seems like there is problem with importing DLL's for fiona – skrhee Sep 12 '19 at 21:51

1 Answers1

1

As far as another library is concerned: you can use cx_Freeze to make an executable out of your Python program.

You can install cx_Freeze by issuing the command

python -m pip install cx_Freeze --upgrade

in a terminal or command prompt. You'll find links to the cx_Freeze documentation and source code on the cx_Freeze entry page.

To create an executable, you need to create a setup script setup.py for your application an then issue the command

python setup.py build

You can find a working example using tkinterin this question

tkinter program compiles with cx_Freeze but program will not launch

and its accepted answer. It also contains useful links.

In order to use pandas in your main script, you'll need to modify the setup.py script of the example linked above by adding

packages = ['numpy']

and replacing the options argument in the setup call by

options={'build_exe': {'include_files': include_files, 'packages': packages}}

You also might need further tweaking for the other modules you are using (geopandas, folium, ...). If it does not work with the example described above, please edit your question and add the setup.py script you are using and the error message reported to get further help.

EDIT:

For cx_Freeze version 5.1.1, the TCL/TK DLLs need to be included in a lib subdirectory of the build directory. You can do that by passing a tuple (source, destination) to the corresponding entry of the include_files list option:

include_files = [(os.path.join(PYTHON_INSTALL_DIR, 'DLLs', 'tk86t.dll'), os.path.join('lib', 'tk86t.dll')),
                 (os.path.join(PYTHON_INSTALL_DIR, 'DLLs', 'tcl86t.dll'), os.path.join('lib', 'tcl86t.dll'))]

As far as the backend is concerned, if you use import backend in frontend.py, it should be no problem, cx_Freeze should freeze it correctly.

jpeg
  • 2,372
  • 4
  • 18
  • 31
  • I've updated my question according to your comment! Thanks – omrakn Jan 22 '19 at 08:20
  • @omrakn Which version of `cx_Freeze` are you using? And do you need to run your backend script as a standalone executable as well? – jpeg Jan 25 '19 at 09:42
  • cx_freeze version is 5.1.1. yeah I need them to be same folder to execute my frontend. – omrakn Jan 29 '19 at 12:52
  • @omrakn I've edited my answer for cx_Freeze 5.1.1. It still do not completely understand how the backend is started, if you still have problems please add the piece of code from your frontend which starts the backend to your question. – jpeg Jan 29 '19 at 13:07
  • First of all thank you for your interest. I've changed my setup.py like you said but it still doesn't respond. I've editted my post and I've added some code snippet from my backend and frontend to make your understanding better. – omrakn Jan 30 '19 at 10:28
  • @omrakn Thank you for this addition. The way you import and use `backend` should be fine for `cx_Freeze` as far as I understand. I guess that the problem is rather that one (or more) of the modules you use either relies on a DLL which is not detected by `cx_Freeze` or dynamically imports further modules which are also not detected by `cx_Freeze`. Have you tried to run your executable from within a `cmd` prompt, do you get any error message this way? If not, I see no other solution than trying to build a separate [mcve] for each of the modules you include until you've found out the root cause. – jpeg Jan 30 '19 at 10:43
  • For example: start with a minimal `tkinter` application as described in [this question](https://stackoverflow.com/questions/52785654/tkinter-program-compiles-with-cx-freeze-but-program-will-not-launch) and make it work on your system. Add then the modules you need one by one (`numpy`, `pandas`, ...) and check that the unfrozen and frozen applications work at each step. You can for example add a message box to this example application and print there the version of each module you import. – jpeg Jan 30 '19 at 11:01