Repository: pyinstaller/pyinstaller

Issue:
PySide2 QML Graphical Effects not working with PyInstaller
PyInstaller 4.1
Python v3.7
Ubuntu 20.04.1

When I use PyInstaller to bundle my PySide2/QML application. Any graphical effects do not get rendered. I have an example below with LinearGradient that does not work.

main.py

    import sys
    import os
    
    from PySide2.QtGui import QGuiApplication
    from PySide2.QtQml import QQmlApplicationEngine
    
    
    if __name__ == "__main__":
        app = QGuiApplication(sys.argv)
        engine = QQmlApplicationEngine()
        engine.load(os.path.join(os.path.dirname(__file__), "main.qml"))
    
        if not engine.rootObjects():
            sys.exit(-1)
        sys.exit(app.exec_())


main.qml


    import QtQuick 2.15
    import QtQuick.Window 2.15
    import QtGraphicalEffects 1.15
    
    Window {
        width: 640
        height: 480
        visible: true
        title: qsTr("Hello World")
    
        Item {
            width: 300
            height: 300
    
            LinearGradient {
                anchors.fill: parent
                start: Qt.point(0, 0)
                end: Qt.point(0, 300)
                gradient: Gradient {
                    GradientStop { position: 0.0; color: "white" }
                    GradientStop { position: 1.0; color: "black" }
                }
            }
        }
    }

When I run this simple pyinstaller command it succeeds without any errors:

> pyinstaller main.py

    ubuntu@ubuntu:~/Projects/build_test$ pyinstaller main.py
    22 INFO: PyInstaller: 4.1
    22 INFO: Python: 3.7.3
    23 INFO: Platform: Linux-5.0.0-23-generic-x86_64-with-Ubuntu-19.04-disco
    23 INFO: wrote /home/ubuntu/Projects/build_test/main.spec
    24 INFO: UPX is not available.
    25 INFO: Extending PYTHONPATH with paths
    ['/home/ubuntu/Projects/build_test', '/home/ubuntu/Projects/build_test']
    30 INFO: checking Analysis
    30 INFO: Building Analysis because Analysis-00.toc is non existent
    30 INFO: Initializing module dependency graph...
    31 INFO: Caching module graph hooks...
    35 INFO: Analyzing base_library.zip ...
    1820 INFO: Caching module dependency graph...
    1871 INFO: running Analysis Analysis-00.toc
    1893 INFO: Analyzing /home/ubuntu/Projects/build_test/main.py
    1937 INFO: Processing module hooks...
    1937 INFO: Loading module hook 'hook-xml.py' from '/home/ubuntu/.local/lib/python3.7/site-packages/PyInstaller/hooks'...
    2089 INFO: Loading module hook 'hook-PySide2.QtQml.py' from '/home/ubuntu/.local/lib/python3.7/site-packages/PyInstaller/hooks'...
    2257 INFO: Loading module hook 'hook-encodings.py' from '/home/ubuntu/.local/lib/python3.7/site-packages/PyInstaller/hooks'...
    2291 INFO: Loading module hook 'hook-difflib.py' from '/home/ubuntu/.local/lib/python3.7/site-packages/PyInstaller/hooks'...
    2292 INFO: Excluding import of doctest from module difflib
    2292 INFO: Loading module hook 'hook-PySide2.QtCore.py' from '/home/ubuntu/.local/lib/python3.7/site-packages/PyInstaller/hooks'...
    2341 INFO: Loading module hook 'hook-PySide2.py' from '/home/ubuntu/.local/lib/python3.7/site-packages/PyInstaller/hooks'...
    2356 INFO: Loading module hook 'hook-heapq.py' from '/home/ubuntu/.local/lib/python3.7/site-packages/PyInstaller/hooks'...
    2357 INFO: Excluding import of doctest from module heapq
    2357 INFO: Loading module hook 'hook-pickle.py' from '/home/ubuntu/.local/lib/python3.7/site-packages/PyInstaller/hooks'...
    2358 INFO: Excluding import of argparse from module pickle
    2358 INFO: Loading module hook 'hook-PySide2.QtNetwork.py' from '/home/ubuntu/.local/lib/python3.7/site-packages/PyInstaller/hooks'...
    2407 INFO: Loading module hook 'hook-PySide2.QtGui.py' from '/home/ubuntu/.local/lib/python3.7/site-packages/PyInstaller/hooks'...
    2476 INFO: Looking for ctypes DLLs
    2476 INFO: Analyzing run-time hooks ...
    2478 INFO: Including run-time hook '/home/ubuntu/.local/lib/python3.7/site-packages/PyInstaller/hooks/rthooks/pyi_rth_pyside2.py'
    2481 INFO: Looking for dynamic libraries
    7130 INFO: Looking for eggs
    7131 INFO: Python library not in binary dependencies. Doing additional searching...
    7190 INFO: Using Python library /usr/lib/x86_64-linux-gnu/libpython3.7m.so.1.0
    7193 INFO: Warnings written to /home/ubuntu/Projects/build_test/build/main/warn-main.txt
    7207 INFO: Graph cross-reference written to /home/ubuntu/Projects/build_test/build/main/xref-main.html
    7248 INFO: checking PYZ
    7248 INFO: Building PYZ because PYZ-00.toc is non existent
    7248 INFO: Building PYZ (ZlibArchive) /home/ubuntu/Projects/build_test/build/main/PYZ-00.pyz
    7476 INFO: Building PYZ (ZlibArchive) /home/ubuntu/Projects/build_test/build/main/PYZ-00.pyz completed successfully.
    7477 INFO: checking PKG
    7477 INFO: Building PKG because PKG-00.toc is non existent
    7477 INFO: Building PKG (CArchive) PKG-00.pkg
    7499 INFO: Building PKG (CArchive) PKG-00.pkg completed successfully.
    7500 INFO: Bootloader /home/ubuntu/.local/lib/python3.7/site-packages/PyInstaller/bootloader/Linux-64bit/run
    7500 INFO: checking EXE
    7500 INFO: Building EXE because EXE-00.toc is non existent
    7500 INFO: Building EXE from EXE-00.toc
    7500 INFO: Appending archive to ELF section in EXE /home/ubuntu/Projects/build_test/build/main/main
    7504 INFO: Building EXE from EXE-00.toc completed successfully.
    7507 INFO: checking COLLECT
    7507 INFO: Building COLLECT because COLLECT-00.toc is non existent
    7507 INFO: Building COLLECT COLLECT-00.toc
    7967 INFO: Building COLLECT COLLECT-00.toc completed successfully.



I am running the app from the dist/ directory using the command: `./main`

Here is a list of all files and directories in /dist:
https://pastebin.com/raw/2XMmi2yi


Here is the output after running the app with QT_DEBUG_PLUGINS=1:
https://pastebin.com/raw/fHG1th1u


Any idea how to debug this? I can't seem to find any clues... 


Discussion:
Hmm, I think I've seen something like this before.

Does copying `site-packages/PySide2/Qt/plugins/xcbglintegrations/` folder into your `$program_dist/PySide2/plugins/` help?

Resolving patch:
diff --git a/PyInstaller/utils/hooks/qt.py b/PyInstaller/utils/hooks/qt.py
--- a/PyInstaller/utils/hooks/qt.py
+++ b/PyInstaller/utils/hooks/qt.py
@@ -396,7 +396,9 @@ def get_qmake_path(version=''):
     "enginio":                  (None,                     None,               ),
     "qt5gamepad":               (None,                     None,               "gamepads"),
     # Note: The ``platformthemes`` plugin is for Linux only, and comes from earlier PyInstaller code in ``hook-PyQt5.QtGui.py``. The ``styles`` plugin comes from the suggestion at https://github.com/pyinstaller/pyinstaller/issues/2156.
-    "qt5gui":                   (".QtGui",                 "qtbase",           "accessible", "iconengines", "imageformats", "platforms", "platforminputcontexts", "platformthemes", "styles"),
+    # ``xcbglintegrations`` and ``egldeviceintegrations`` were added manually
+    # for linux
+    "qt5gui":                   (".QtGui",                 "qtbase",           "accessible", "iconengines", "imageformats", "platforms", "platforminputcontexts", "platformthemes", "styles", "xcbglintegrations", "egldeviceintegrations"),  # noqa
     "qt5help":                  (".QtHelp",                "qt_help",          ),
     # This entry generated by hand -- it's not present in the Windows deployment tool sources.
     "qt5macextras":             (".QtMacExtras",           None,               ),
@@ -405,14 +407,12 @@ def get_qmake_path(version=''):
     "qt5multimediaquick_p":     (None,                     "qtmultimedia",     ),
     "qt5network":               (".QtNetwork",             "qtbase",           "bearer"),
     "qt5nfc":                   (".QtNfc",                 None,               ),
-    ##                                                                              These added manually for Linux.
-    "qt5opengl":                (".QtOpenGL",              None,               "xcbglintegrations", "egldeviceintegrations"),
+    "qt5opengl":                (".QtOpenGL",              None,               ),  # noqa
     "qt5positioning":           (".QtPositioning",         None,               "position"),
     "qt5printsupport":          (".QtPrintSupport",        None,               "printsupport"),
     "qt5qml":                   (".QtQml",                 "qtdeclarative",    ),
     "qmltooling":               (None,                     None,               "qmltooling"),
-    ##                                                                                                          These added manually for Linux.
-    "qt5quick":                 (".QtQuick",               "qtdeclarative",    "scenegraph", "qmltooling", "xcbglintegrations", "egldeviceintegrations"),
+    "qt5quick":                 (".QtQuick",               "qtdeclarative",    "scenegraph", "qmltooling"),  # noqa
     "qt5quickparticles":        (None,                     None,               ),
     "qt5quickwidgets":          (".QtQuickWidgets",        None,               ),
     "qt5script":                (None,                     "qtscript",         ),
@@ -429,8 +429,7 @@ def get_qmake_path(version=''):
     "qt5winextras":             (".QtWinExtras",           None,               ),
     "qt5xml":                   (".QtXml",                 "qtbase",           ),
     "qt5xmlpatterns":           (".QXmlPatterns",          "qtxmlpatterns",    ),
-    ##                                                                                             These added manually for Linux.
-    "qt5webenginecore":         (".QtWebEngineCore",       None,               "qtwebengine", "xcbglintegrations", "egldeviceintegrations"),
+    "qt5webenginecore":         (".QtWebEngineCore",       None,               "qtwebengine"),  # noqa
     "qt5webengine":             (".QtWebEngine",           "qtwebengine",      "qtwebengine"),
     "qt5webenginewidgets":      (".QtWebEngineWidgets",    None,               "qtwebengine"),
     "qt53dcore":                (None,                     None,               ),


Test patch: