Recipe PyQt4 API Version
PyQt4 supports two different APIs: version 1 (default on Python 2) and version 2 (default on Python 3). It is possible to change API at runtime through the sip.setapi
call; a good example is that someone wants to write API v2 code on Python 2 to be future-proof and ready for the migration to Python 3.
Alas, changing API versions does not currently work with PyInstaller, and leads to error messages such as:
ValueError: API 'QString' has already been set to version 1
In the development version of PyInstaller a good workaround is to create a runtime hook file that is executed before the runtime hook support/rthooks/pyi_rth_qt4plugins.py
in PyInstaller, and add the API changing code at the top of your custom runtime hook. Let's name the file rthook_pyqt4.py
.
Then add there code:
import sip
sip.setapi(u'QDate', 2)
sip.setapi(u'QDateTime', 2)
sip.setapi(u'QString', 2)
sip.setapi(u'QTextStream', 2)
sip.setapi(u'QTime', 2)
sip.setapi(u'QUrl', 2)
sip.setapi(u'QVariant', 2)
Then rebuild your application with the --runtime-hook
option
pyinstaller.py --runtime-hook rthook_pyqt4.py main_script.py
or add runtime_hooks
argument to the Analysis object in your .spec file
a = Analysis(['main_script.py'],
pathex=[],
hiddenimports=[],
hookspath=None,
runtime_hooks=['rthook_pyqt4.py'])
and it should work with PyInstaller.
Unless the problem is fixed, a good workaround is to edit the file support/rthooks/pyi_rth_qt4plugins.py
in PyInstaller, and add the API changing code at the top of it. Code like in previous section.