3
votes

So, I have two .py files, one generated by QtDesigner and another which basically implements the functionality of the GUI. Using, pyinstaller, I generated a .exe file to use it on systems without python and the associated libraries.

The command: pyinstaller my_script.py runs fine without any errors.

The problem occurs when I run the .exe file.

Error:

Qt: Untested Windows version 10.0 detected! Traceback (most recent call last): File "site-packages\PyInstaller\loader\rthooks\pyi_rth_qt4plugins.py", line 41, in ImportError: No module named 'PySide'

During handling of the above exception, another exception occurred:

Traceback (most recent call last): File "site-packages\PyInstaller\loader\rthooks\pyi_rth_qt4plugins.py", line 43, in File "", line 2237, in _find_and_load File "", line 2226, in _find_and_load_unlocked File "", line 1191, in _load_unlocked File "", line 1161, in _load_backward_compatible File "C:\python\lib\site-packages\PyInstaller\loader\pyimod03_importers.py", line 714, in load_module module = loader.load_module(fullname)

RuntimeError: the PyQt4.QtCore and PyQt5.QtCore modules both wrap the QObject class [11364] Failed to execute script pyi_rth_qt4plugins

So I tried to find a solution to this. These are the solutions I tried:

How to force PyQt5 use for QObject class? - simply make the PyQt import as the first statement doesn't resolve the issue.

https://github.com/tzutalin/labelImg/issues/268 - Here it is recommended to remove PyQt4 and use only PyQt5. I do have both of them on my system, some projects rely on PyQt5 and some on PyQt4 hence I don't want remove the latter. Also, there has to be another solution, is making me not do this.

https://intellij-support.jetbrains.com/hc/en-us/community/posts/115000551170-PyQt4-and-PyQt5-collisions-in-PyCharm-2017-2-1-when-debugging-QGIS-application - This was a similar error, so I added: matplotlib.rcParams['backend'] = 'Qt4Agg' matplotlib.rcParams['backend.qt4'] = 'PyQt4'

to my imports, still didn't work.

Note: I am using:

PyCharm 2018.1 (Community Edition)

Build #PC-181.4203.547, built on March 26, 2018

JRE: 1.8.0_152-release-1136-b20 amd64

JVM: OpenJDK 64-Bit Server VM by JetBrains s.r.o

Windows 10 10.0

and the code works fine in the IDE.

EDIT:

My imports are:

from PyQt4 import QtCore, QtGui
from matplotlib.backends.backend_qt4agg import FigureCanvasQTagg as Canvas

I am not adding any other import statements related to Qt.

EDIT - 2:

Trying cx_Freeze instead of PyInstaller, here is the setup file.

import sys
from cx_Freeze import setup, Executable

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

additional_mods = ['numpy.core._methods', 'numpy.lib.format', 
'numpy._distributor_init']

setup( name="ASCII2fig",
       version = "0.1",
       description = "GUI",
       options = {'build_exe': {'includes': additional_mods}},
       executables = [Executable("ASCII2figALL_main_edited.py", base=base)])

I added the additional_mods after executing the script once following ImportError, which are non-stop. Any ways to hack and find which libraries I should mention explicitly?

Additionally, I also tried to check which libraries are actually being imported when I run my main script with Qt using:

from modulefinder import ModuleFinder

filename = "ASCII2figALL_main_edited.py"
finder = ModuleFinder()
finder.run_script(filename)
for name, mod in finder.modules.items():
    print(name)

and apparently, it is importing PyQt5 internally. As mentioned before, I have NO import statements mentioning PyQt5.

Edit - 3

So, I changed the code to pure PyQt5, updated the pyinstaller to the latest version - 3.4, and now there is a new issue where it doesn't find the Qt plugins. It is still somehow importing PyQt4 and I don't know where.

1
are you against using another exe compiler? I use cx_Freeze for all of my PyQt projects and it always works well with minimal tweeks to the setup code.SRT HellKitty
Yes, as I mentioned, I am using pyinstaller. I can give cx_Freeze a try. But it still bugs me why this hasn't been fixed.Rick M.
Why are there all possible Qt-Python bindings raising some errors (PySide, PyQt4, PyQt5) ? Do you use them all at once ? Usually most 'compilers' should handle PyQt fine out of the box.Maurice Meyer
@MauriceMeyer Not in this file I don't, here I am using only PyQt4. I added the imports as an editRick M.
it shouldn't be that difficult. It is absolutely not as easy as pyinstaller, however once you find the dependencies correct it should be quick and easy. Do you mind posting the setup.py you have? I am not sure what you mean by manually add libraries, some do not load correctly(tkinter, some numpy), but you can "include" them in the setup.SRT HellKitty

1 Answers

1
votes

So, I finally made it to work. Not the ideal case, where I don't have to change the library to PyQt5 and make sure everything is in order with PyInstaller, but it works. So here is what I did:

  1. Installed Python version 3.5 - This was because after I updated to the latest PyInstaller version (3.4) and tried to run on python 3.4, I was getting a new error where it was not able to find Qt plugins. After some searching, I figured that since I installed PyQt5 on Python version (3.4) using a .whl file I found on Python Extension Packages for Windows, the installation didn't come bundled with sip. Additionally, when I tried to install PyQt5 on Python 3.4 using pip, it wouldn't install.

  2. Installed PyQt5 and all other libraries on the new Python version using pip. Note: This version of python doesn't have a PyQt4 installed, so it is quite possible that this was the reason. I will install PyQt4 on this python version and try making the .exe again using PyInstaller and see what happens.

So, to summarize, PyQt5 + Pyinstaller works only for Python version >= 3.5. Hope it helps others!