11

I am trying to bundle a PyQt project using Pyinstaller. I tried creating package using command pyinstaller --onedir Hello.py.

This creates dist folder and has Hello.exe. On running it gets the error: This application failed to start because it could not find or load the Qt platform plugin "windows"in "". Reinstalling the application may fix this problem.

I solved the issue in my PC by

  1. setting environment variable QT_QPA_PLATFORM_PLUGIN_PATH

or by

  1. Copying dist\Hello\PyQt5\Qt\plugins\platform folder to where Hello.exe exists.

But this issue exists when I bundle to a single file using command --onefile, and run on any other machine, where QT_QPA_PLATFORM_PLUGIN_PATH is not set.

Can someone help to figure out the issue.

A.J
  • 725
  • 10
  • 33

4 Answers4

0

This is a problem a lot of people were struggling with (including myself). See for example this bug report.

Suggestion 1 (recommended): upgrade to pyinstaller v3.4. According to this pull request, several issues have been solved, in particular the one the OP is referring to. There is generally better support for PyQt5 now.

Suggestion 2: this one worked for me, but is not recommended. It may help for older versions of PyQt5 or if you are not able to upgrade to pyinstaller 3.4: Locate the site-packages directory of your python distribution and apply the following two changes to the PyInstaller module:

Edit 1: PyInstaller/loader/rthooks.dat
-    'PyQt5':      ['pyi_rth_qt5.py'],
+    'PyQt5':      ['pyi_rth_qt5.py', 'pyi_rth_qt5plugins.py'],
Edit 2: PyInstaller/utils/hooks/qt.py
-    elif namespace == 'PyQt5':
-        plugin_dir = os.path.join('PyQt5', 'Qt', 'plugins')

Source: see pull request #2991 by user shadchin.

(I further recommend to use python 3.x. I struggled to bundle PyQt5 successfully for python 2.7.x, but I do not remember if the problems occurred on windows or macOS.)

normanius
  • 8,629
  • 7
  • 53
  • 83
0

If you using python 3.4 and pip refuses to install pyqt5

Download and install

Pyqt5 manually to %your python 3.4 dir%

Create directory

Go to %your python 3.4 dir%\Lib\site-packages\PyQt5 create directory Qt and then move plugins folder there.

Add plugins

Then you can add ('C:/Python34-32/Lib/site-packages/PyQt5/Qt/plugins', 'PyQt5/Qt/plugins') to data in your spec file.

be sure to download PyQt 5.4.1 or other version that supports python 3.4

At least that solved my problem. I hope this will help somebody

Prakash Krishna
  • 1,239
  • 6
  • 12
Karmen
  • 1
  • 2
0

I wrote a similar answer to the same question as I have been struggling with this issue too. Just like you I tried to set the environment path and copy the folder (which worked but again it has to be done manually. If you look at the top of your generated .spec file you'll see mode: python so that gave me an idea as you can see below:

# -*- mode: python ; coding: utf-8 -*-

block_cipher = None

pf_foldr='C:\\Users\\Gabryxx7\\anaconda3\\envs\\<env_name>\\Library\\plugins\\platforms\\'

a = Analysis(['C:\\Users\\Gabryxx7\\PycharmProjects\\<proj_name>\\program.py'],
             pathex=['C:\\Users\\Gabryxx7\\PycharmProjects\\<proj_name>\\'],
             binaries=[(pf_foldr+'qwindows.dll', 'platforms\\qwindows.dll'),
             (pf_foldr+'qdirect2d.dll', 'platforms\\qdirect.dll'),
             (pf_foldr+'qoffscreen.dll', 'platforms\\qoffscreen.dll'),
             (pf_foldr+'qwebgl.dll', 'platforms\\qwebgl.dll')
             ],
             datas=[],
             hiddenimports=['GUI', 'API', 'Threading', 'ssl', 'pyodbc'],
             hookspath=[],
             runtime_hooks=[],
             excludes=[],
             win_no_prefer_redirects=False,
             win_private_assemblies=False,
             cipher=block_cipher,
             noarchive=False)
pyz = PYZ(a.pure, a.zipped_data,
             cipher=block_cipher)
exe = EXE(pyz,
          a.scripts,
          a.binaries,
          a.zipfiles,
          a.datas,
          [],
          name='programName',
          debug=False,
          bootloader_ignore_signals=False,
          strip=False,
          upx=True,
          upx_exclude=[],
          runtime_tmpdir=None,
          console=True ) # False to avoid the console

This is a sample for a --one-file spec. As it says on the docs: https://pyinstaller.readthedocs.io/en/stable/spec-files.html

In one-file mode, there is no call to COLLECT, and the EXE instance receives all of the scripts, modules and binaries.

While for the binaries, each binary should be a tuple with two values:

The first string specifies the file or files as they are in this system now. The second specifies the name of the folder to contain the files at run-time.

Gabryxx7
  • 11
  • 3
0

I've had success using auto-py-to-exe which builds the commands for pyinstaller automatically based on the options you choose:

pip install auto-py-to-exe

Then use it using:

auto-py-to-exe

Documentation: https://pypi.org/project/auto-py-to-exe/

Archived Documentation: https://archive.ph/2Cw0x

Matt Binford
  • 620
  • 8
  • 15