mherrmann / fbs

Create Python GUIs with Qt in minutes
https://build-system.fman.io
GNU General Public License v3.0
3.81k stars 195 forks source link

Freeze issues when working with TrackPy #219

Open vivien-walter opened 4 years ago

vivien-walter commented 4 years ago

I had quite a struggle making an app recently with fbs because I am using the package TrackPy. The app would start smoothly with fbs run but keeps crashing after the fbs freeze was completed successfully. I am using MacOSX here, and I could not get any information from fbs freeze --debug. Although, starting the app with ./target/app_name/app_name would display the really helpful error message.

The problem does not come from the TrackPy package itself but from several dependencies so I thought it would be interesting to share this issue - especially since using TrackPy makes totally sense in a GUI environment, so I can foresee that more people might look for a way to solve the problem. Moreover I was not able to reproduce the issue with PyInstaller, so I think it makes sense to share the issue(s) here instead of there.

The error message should be easily obtained by following these steps: (1) create a virtualenv, (2) install with pip fbs, PyQt5 and trackpy, (3) run fbs startproject, (4) open the file main.py and add the line import trackpy in the header, then (5) run fbs freeze and test the app.

The problem(s) with TrackPy I have found mostly comes from (i) matplotlib and (ii) scipy

  1. First, similarly to the issue with Homebrew discussed in #205 and as related to this post I found on StackOverflow, SciPy itself would seem to load fine with fbs, but it doesn't when called by TrackPy. The typical output error I found here is

    > ModuleNotFoundError: No module named 'scipy.special.cython_special'

    The way to solve the problem is the same than in both post linked above: SciPy must be installed first, and restricted to the version 1.4.1

    pip install scipy==1.4.1
  2. Matplotlib has a first issue that I only got when used combined with TrackPy (it would load fine otherwise). The message returned when calling the app was

    > NameError: name 'defaultParams' is not defined

    Similarly to the issue with SciPy, this is a problem caused by a too recent version of matplotlib being used. This was discussed again on StackOverflow. The solution given there worked for me, so it is essential to install matplotlib before TrackPy and to set the version to 3.2.2.

    pip install matplotlib==3.2.2

    I would also like to note here that this get rid of the deprecation warning discussed in #205 - although it was not what I was looking to fix.

  3. Finally, the second issue with matplotlib is obviously the Tcl/Tk installation issue discussed back in #88 and on pyinstaller/pyinstaller/issues/3753. The solution here still work perfectly fine.

I hope these feedbacks and solutions can be useful to other users. I pasted the error messages to make it perhaps easier to find with the search tool. Due to their nature, I don't think any of these errors require an update of the code of fbs.

vivien-walter commented 3 years ago

Hi Michael,

Apologies for re-opening this issue that I closed myself 16 days ago. At that time, the solution I provided worked just fine... except I was on MacOS X, and now that my App is complete (thanks again for the wonderful package, fbs is so helpful) I needed to release it as a .exe executable for Windows 10 users as well. And here, SciPy is giving me a complete headache.

When some of SciPy functions are called, such as scipy.spatial (which is required by other package such as TrackPy) or other packages such as scikit-image for example, the issue(s) I keep getting after doing fbs freeze and executing the script are like:

File "site-packages\scipy\spatial\__init__.py", line 99, in <module>
ImportError: DLL load failed: The specified module could not be found.

To reproduce this problem, I just had to do a fbs startproject and add a import scipy.spatial line. Resulting script looks like that

from fbs_runtime.application_context.PyQt5 import ApplicationContext
from PyQt5.QtWidgets import QMainWindow

import sys
import scipy.spatial

if __name__ == '__main__':
    appctxt = ApplicationContext()       # 1. Instantiate ApplicationContext
    window = QMainWindow()
    window.resize(250, 150)
    window.show()
    exit_code = appctxt.app.exec_()      # 2. Invoke appctxt.app.exec_()
    sys.exit(exit_code)

Using the suggestion from the fbs Manual, the first thing I did was to edit the hidden-imports of the base.json file to write

"hidden-imports": ["scipy","scipy.spatial"]

But no difference. I then looked at similar issues being reported with PyInstaller, such as this one https://github.com/pyinstaller/pyinstaller/issues/3197 or this one https://github.com/pyinstaller/pyinstaller/issues/4559 , but I didn't find much more because between PyInstaller 3.4 and 4.0 the issue have been fixed (ie import scipy.spatial won't cause the executable to fail starting).

After checking it myself, I tried to force in my virtualenv PyInstaller to be at version 4.0 while working with fbs. And this time, after a fbs freeze, the generated executable (from the code above) worked perfectly. I applied it to my App (the one I am really interested in) and it worked as well.

While my App is working now, I think this can be a major issue for fbs if anyone wants to use specific functions from SciPy. I am not 100% why fbs requires PyInstaller 3.4, but it seems that this version of PyInstaller is flawed.

More details about the config of the computer used for the tests:

Hope it can be of any help to you!

jason-SEMCdev commented 2 years ago

I think the key is hidden_imports, you can check to see if it is parsed by looking in the: /target/PyInstaller/[appName].spec in the Analysisobject's hiddenimportslist.

Still can't get these extra modules to load in a frozen app if I've changed the code to be in a different location, ie.- main/python/[sub-path]