0

Using cx_Freeze with PyQt5, I get the following error:

ImportError: No module named 'PyQt5.Qt'

My setup.py file is as follows:

from cx_Freeze import setup, Executable

base = None

executables = [Executable("Chemistry.py", base=base)]

packages = ["idna", "sys", "pandas", "PyQt5"]
options = {
    'build_exe': {
        'packages':packages,
    },
}

setup(
    name = "<any name>",
    options = options,
    version = "<any number>",
    description = '<any description>',
    executables = executables
)

How do I fix this error? I am using Windows OS.

jpeg
  • 2,372
  • 4
  • 18
  • 31
user1655130
  • 419
  • 1
  • 3
  • 13
  • Do you get the error while trying to build (launching the cx_Freeze setup) or while you try to run the executable? – musicamante Aug 28 '19 at 16:52
  • While I try to build the application. I'm completely lost with it. – user1655130 Aug 28 '19 at 17:19
  • Can you edit your question with the complete error output? – musicamante Aug 28 '19 at 19:41
  • @eyllanesc I would suggest to swap the source and target of this duplicate pair, because this question has an accepted answer, and the other doesn't and probably will never have (its OP seems to have left SO). This question seems me also a better canonical (easier to understand). However the other question has a better title, one would also probably need to edit both titles. – jpeg Aug 29 '19 at 11:43
  • @jpeg The duplicate does not depend on whether there is an accepted answer, besides the duplicate does not aim to indicate that something is better than another, it only aims to indicate that an answer already existed and you indicated it in a comment, finally a duplicate does not imply The elimination of publications only explicitly indicates the relationship between the questions. – eyllanesc Aug 29 '19 at 14:19

1 Answers1

2

Try this solution to a similar question:

  1. Remove "PyQt5" from the packages list
  2. Let cx_Freeze copy the whole PyQt5 directory into the lib subdirectory of the build directory. You can do that by passing a (source, destination) tuple to the include_files list, which tells cx_Freeze to copy the source (a file or a whole directory) to a destination relative to the build directory (see the cx_Freeze documentation). Set the source to os.path.dirname(PyQt5.__file__), which gives the directory of the PyQt5 package (through its __init__.py file) of your Python installation, and the destination to "lib".
  3. Furthermore, if your application really uses pandas, you also need to add "numpy" to the packages list, see cx_Freeze not able to build msi with pandas and Creating cx_Freeze exe with Numpy for Python

Altogether, try modify your setup.py script as follows:

import os
import PyQt5
include_files = [(os.path.dirname(PyQt5.__file__), "lib")]
packages = ["idna", "sys", "numpy", "pandas"]
options = {
    'build_exe': {
        'include_files':include_files,
        'packages':packages,
    },
}
jpeg
  • 2,372
  • 4
  • 18
  • 31
  • 1
    This worked brilliantly. I was struggling with this for days. Thanks so much – user1655130 Aug 29 '19 at 09:11
  • What does this line of code do `include_files = [(os.path.dirname(PyQt5.__file__), "lib")]` – user1655130 Aug 29 '19 at 09:12
  • 1
    @user1655130 I've added an explanation to my answer. – jpeg Aug 29 '19 at 11:33
  • I went to re-run this exact same code today and now I get the following error: `TypeError: expected str, bytes or os.PathLike object, not NoneType` which is coming from this line: `include_files = [(os.path.dirname(PyQt5.__file__), "lib")]` Any ideas why this is? Thanks – user1655130 Sep 04 '19 at 08:48
  • This could be because the `__file__` attribute is not set in all cases. In particular, it is not present for C modules that are statically linked into the interpreter, see [what does the `__file__` variable mean/do?](https://stackoverflow.com/questions/9271464/what-does-the-file-variable-mean-do). Can it be that you reran the same code from the interpreter this time, and the previous time from a `cmd` prompt? – jpeg Sep 09 '19 at 12:48