Skip to content

Commit 9ac7767

Browse files
committed
Standalone exe version 1.1, compatibility with PyInstaller 3.2.1
Fixed: Ensure API version 2 for PyQT4 in PyInstaller (non functional setting dialogs)
1 parent 6482575 commit 9ac7767

7 files changed

Lines changed: 98 additions & 56 deletions

File tree

HowTo-Windows-Exe.txt

Lines changed: 21 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,33 +1,38 @@
1-
Instructions for building the Windows executable using PyInstaller 2.1:
1+
Instructions for building the Windows executable using PyInstaller 3.2.1 on Python 2.7.10
22

3-
Note: As of April 2016 PyInstaller 3.0 does not work properly
4-
5-
1. Make sure PyInstaller 2.1 is installed in your Python environment!
3+
1. Make sure PyInstaller 3.2.1 is installed in your Python environment!
64

75
2. Open the file build_exe.py and adjust the directories if required.
86

9-
3. Extremely important: Make sure that in main.py the line
10-
sip.setapi('QVariant', 2)
11-
is commented out:
12-
#sip.setapi('QVariant', 2)
13-
14-
4. In your python installation locate the directory in which the
7+
3. In your python installation locate the directory in which the
158
mpl_toolkits reside. Put an empty file named __init__.py into it
169
(e.g. c:\Progs32\WinPython-32bit-2.7.10.3\python-2.7.10\Lib\site-packages\mpl_toolkits\__init__.py)
1710

11+
12+
4. In your python installation locate file build_main.py in the PyInstaller\building directory
13+
(e.g. C:\Progs32\WinPython-32bit-2.7.10.3\python-2.7.10\Lib\site-packages\PyInstaller\building\build_main.py)
14+
Open this file and go to the function "build(spec, distpath, workpath, clean_build)". Insert the line
15+
16+
sys.setrecursionlimit(2147483647)
17+
18+
just below the imports. Save the file. (This is to fix a bug on PyInstaller / modulegraph, see
19+
comment in PyInstaller\lib\modulegraph\modulegraph.py:
20+
#FIXME: To decrease the likelihood of ModuleGraph exceeding the recursion limit
21+
#and hence unpredictably raising fatal exceptions, increase the recursion
22+
#limit at PyInstaller startup (i.e., in the
23+
#PyInstaller.building.build_main.build() function). For details, see:
24+
# https://github.com/pyinstaller/pyinstaller/issues/1919#issuecomment-216016176 )
25+
1826
5. Make sure that build_dir is not opened in any application or console, i.e.,
1927
it can be deleted by the script.
2028

2129
6. Run build_exe.py
2230

23-
7. The resulting exe should be found in build_dir.
31+
7. The resulting exe should be found in build_dir\PyPlane.
2432

2533
8. If some modules are not found after launching the exe you have to manually
2634
import them using the --hidden-import option in build_exe. This can be
2735
a time-consuming trial and error procedure.
2836

29-
9. Change the line
30-
#sip.setapi('QVariant', 2)
31-
in main.py to
32-
sip.setapi('QVariant', 2)
33-
to ensure that the application runs properly under native Python.
37+
9. Open the file InstallerPyPlane.nsi, adjust the version information if required, and run the
38+
file through NullSoft Installable System. Setup.exe will be placed into build_dir.

InstallerPyPlane.nsi

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
; HM NIS Edit Wizard helper defines
44
!define PRODUCT_NAME "PyPlane"
5-
!define PRODUCT_VERSION "1.0"
5+
!define PRODUCT_VERSION "1.1"
66
!define PRODUCT_PUBLISHER "Institut fuer Regelungs- und Steuerungstheorie"
77
!define PRODUCT_WEB_SITE "https://github.com/TUD-RST/pyplane.git"
88

PyPlane.spec

Lines changed: 18 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,33 @@
11
# -*- mode: python -*-
2+
3+
block_cipher = None
4+
5+
26
a = Analysis(['main.py'],
3-
pathex=['core', 'D:\\Users\\winkler\\Uni\\Projekte\\Allgemein\\pyplane'],
7+
pathex=['core', 'D:\\winkler\\Uni\\Projekte\\Allgemein\\pyplane\\pyplane'],
8+
binaries=[],
9+
datas=[],
410
hiddenimports=['scipy.special._ufuncs_cxx', 'mpl_toolkits', 'scipy.linalg.cython_blas', 'scipy.linalg.cython_lapack'],
5-
hookspath=None,
6-
runtime_hooks=None)
7-
pyz = PYZ(a.pure)
11+
hookspath=[],
12+
runtime_hooks=['runtime_hook_pyqt4.py'],
13+
excludes=[],
14+
win_no_prefer_redirects=False,
15+
win_private_assemblies=False,
16+
cipher=block_cipher)
17+
pyz = PYZ(a.pure, a.zipped_data,
18+
cipher=block_cipher)
819
exe = EXE(pyz,
920
a.scripts,
1021
exclude_binaries=True,
11-
name='PyPlane.exe',
22+
name='PyPlane',
1223
debug=False,
13-
strip=None,
24+
strip=False,
1425
upx=True,
1526
console=True , icon='resources\\pyplane_icon_32px.ico')
1627
coll = COLLECT(exe,
1728
a.binaries,
1829
a.zipfiles,
1930
a.datas,
20-
strip=None,
31+
strip=False,
2132
upx=True,
2233
name='PyPlane')

README.md

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ https://github.com/TUD-RST/pyplane
3737
Please don't hesitate to report bugs, comments, or suggestions on
3838
GitHub!
3939

40-
[1] http://www.et.tu-dresden.de/rst/
40+
[1] https://tu-dresden.de/ing/elektrotechnik/rst
4141

4242

4343

@@ -55,11 +55,11 @@ Prerequisites for running natively under Python
5555
PyPlane runs under Python version 2.7 with the following packages
5656
installed:
5757

58-
* NumPy (tested under version 1.9)
59-
* SciPy (tested under version 0.15)
60-
* Matplotlib (tested under verison 1.4.3)
61-
* SymPy (tested under verison 0.7.6)
62-
* PyQt4 (tested under version 4.11.3)
58+
* NumPy (tested under version 1.9.3)
59+
* SciPy (tested under version 0.16.1)
60+
* Matplotlib (tested under verison 1.5.0)
61+
* SymPy (tested under verison 0.7.6.1)
62+
* PyQt4 (tested under version 4.11.4)
6363

6464
An optionally installed and accessible LaTeX/dvipng environment
6565
produces much prettier results in the linearization tabs. If no LaTeX
@@ -85,9 +85,12 @@ functional.
8585
Double-click on the PyPlane icon on the desktop in order to launch the
8686
application. Start-up may take some time.
8787

88-
Open issues in version 1.0
88+
Open issues in version 1.1
8989
==========================
9090

91+
* When creating the phase plane plot for a linearized system the creation of the plot title
92+
via LaTeX fails. Workaround: Just plot the streamlines or an arbitrary trajectory in the plot and
93+
the title will appear.
9194
* PyPlane will not launch if it detects a fully functional
9295
LaTeX-environment in which the package type1cm.sty is
9396
missing. Please place this style package in your LaTeX-installation.

build_exe.py

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,15 +6,15 @@
66
77
Please note in order to build a properly working exe:
88
-> Include the statement "import FileDialog" in main.py (an error in matplotlib)
9+
-> Ensure that runtime_hook_pyqt4.py is called when building the target
10+
(option --runtime-hook in call of pyinstaller)
11+
-> Set recursion limit in build_main.py of your PyInstaller installation
12+
(see HowTo-Windows-Exe.txt for more information)
913
1014
Created on Fri Mar 27 16:16:28 2015
1115
1216
@author: winkler
1317
"""
14-
15-
16-
17-
1818
import subprocess
1919
import os.path
2020
import shutil
@@ -33,11 +33,13 @@
3333
paths = 'core'
3434

3535

36+
# Some packages have to be imported manually (--hidden-import)
3637
cmd = 'pyinstaller --clean --distpath=%s --workpath=%s --paths=%s \
3738
--hidden-import=scipy.special._ufuncs_cxx\
3839
--hidden-import=mpl_toolkits\
3940
--hidden-import=scipy.linalg.cython_blas\
4041
--hidden-import=scipy.linalg.cython_lapack\
42+
--runtime-hook runtime_hook_pyqt4.py\
4143
--icon=resources\pyplane_icon_32px.ico --name=%s %s' % (build_dir, temp_dir, paths, exename, infile)
4244
print 'Calling:', cmd
4345

@@ -53,7 +55,6 @@
5355

5456

5557
# Copy the config directory to the build directory
56-
5758
shutil.copytree(config_dir, exe_dir+config_dir)
5859
shutil.copytree(lib_dir, exe_dir+lib_dir)
5960
os.mkdir(os.path.dirname(exe_dir+descrfile))

main.py

Lines changed: 20 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,28 +1,28 @@
11
# -*- coding: utf-8 -*-
2-
3-
# Copyright (C) 2013
4-
# by Klemens Fritzsche, pyplane@leckstrom.de
5-
#
6-
# This program is free software: you can redistribute it and/or modify
7-
# it under the terms of the GNU General Public License as published by
8-
# the Free Software Foundation, either version 3 of the License, or
9-
# (at your option) any later version.
10-
#
11-
# This program is distributed in the hope that it will be useful,
12-
# but WITHOUT ANY WARRANTY; without even the implied warranty of
13-
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14-
# GNU General Public License for more details.
15-
#
16-
# You should have received a copy of the GNU General Public License
17-
# along with this program. If not, see <http://www.gnu.org/licenses/>.
18-
2+
"""
3+
Copyright (C) 2013
4+
by Klemens Fritzsche, pyplane@leckstrom.de
5+
6+
This program is free software: you can redistribute it and/or modify
7+
it under the terms of the GNU General Public License as published by
8+
the Free Software Foundation, either version 3 of the License, or
9+
(at your option) any later version.
10+
11+
This program is distributed in the hope that it will be useful,
12+
but WITHOUT ANY WARRANTY; without even the implied warranty of
13+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14+
GNU General Public License for more details.
15+
16+
You should have received a copy of the GNU General Public License
17+
along with this program. If not, see <http://www.gnu.org/licenses/>.
18+
"""
1919
__author__ = 'Klemens Fritzsche'
2020

2121
import sys
2222
#import ast
2323

24-
# Needed since apparently different default variant types are used under Windows and Linux
25-
# The line sip.setapi(...) has to be commented out if an MS windows exe is built using PyInstaller!
24+
# Ensure that the proper PyQT4 API version is used (otherwise dialogs using
25+
# QVariant do not work)
2626
import sip
2727
sip.setapi('QVariant', 2)
2828

@@ -50,7 +50,7 @@ class MainApp(PyplaneMainWindow):
5050
"""
5151

5252
__PYPLANE_VERSION = "1.1"
53-
__PYPLANE_DATE = "2016-04-08"
53+
__PYPLANE_DATE = "2017-06-17"
5454

5555
def __init__(self):
5656
# superclass constructor

runtime_hook_pyqt4.py

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
# -*- coding: utf-8 -*-
2+
"""
3+
This stuff is needed for building the stand-alone executable. It is called by
4+
the pyinstaller script (via the --runtime-hook flag) and ensures that the
5+
proper API version for PyQT4 is loaded. PyPlane uses the API version 2, but
6+
by default PyInstaller enables API version 1 resulting in non functional
7+
setting dialogs where the datatype QVariant plays an important role.
8+
9+
Created on Wed Jun 14 15:49:26 2017
10+
11+
@author: winkler
12+
"""
13+
14+
import sip
15+
16+
sip.setapi(u'QDate', 2)
17+
sip.setapi(u'QDateTime', 2)
18+
sip.setapi(u'QString', 2)
19+
sip.setapi(u'QTextStream', 2)
20+
sip.setapi(u'QTime', 2)
21+
sip.setapi(u'QUrl', 2)
22+
sip.setapi(u'QVariant', 2)

0 commit comments

Comments
 (0)