pyi_rth_pyside2.py 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263
  1. #-----------------------------------------------------------------------------
  2. # Copyright (c) 2013-2023, PyInstaller Development Team.
  3. #
  4. # Licensed under the Apache License, Version 2.0 (the "License");
  5. # you may not use this file except in compliance with the License.
  6. #
  7. # The full license is in the file COPYING.txt, distributed with this software.
  8. #
  9. # SPDX-License-Identifier: Apache-2.0
  10. #-----------------------------------------------------------------------------
  11. # The path to Qt's components may not default to the wheel layout for self-compiled PySide2 installations. Mandate the
  12. # wheel layout. See ``utils/hooks/qt.py`` for more details.
  13. def _pyi_rthook():
  14. import os
  15. import sys
  16. from _pyi_rth_utils import is_macos_app_bundle, prepend_path_to_environment_variable
  17. from _pyi_rth_utils import qt as qt_rth_utils
  18. # Ensure this is the only Qt bindings package in the application.
  19. qt_rth_utils.ensure_single_qt_bindings_package("PySide2")
  20. if sys.platform.startswith('win'):
  21. pyqt_path = os.path.join(sys._MEIPASS, 'PySide2')
  22. else:
  23. pyqt_path = os.path.join(sys._MEIPASS, 'PySide2', 'Qt')
  24. os.environ['QT_PLUGIN_PATH'] = os.path.join(pyqt_path, 'plugins')
  25. if is_macos_app_bundle:
  26. # Special handling for macOS .app bundles. To satisfy codesign requirements, we are forced to split `qml`
  27. # directory into two parts; one that keeps only binaries (rooted in `Contents/Frameworks`) and one that keeps
  28. # only data files (rooted in `Contents/Resources), with files from one directory tree being symlinked to the
  29. # other to maintain illusion of a single mixed-content directory. As Qt seems to compute the identifier of its
  30. # QML components based on location of the `qmldir` file w.r.t. the registered QML import paths, we need to
  31. # register both paths, because the `qmldir` file for a component could be reached via either directory tree.
  32. pyqt_path_res = os.path.normpath(
  33. os.path.join(sys._MEIPASS, '..', 'Resources', os.path.relpath(pyqt_path, sys._MEIPASS))
  34. )
  35. os.environ['QML2_IMPORT_PATH'] = os.pathsep.join([
  36. os.path.join(pyqt_path_res, 'qml'),
  37. os.path.join(pyqt_path, 'qml'),
  38. ])
  39. else:
  40. os.environ['QML2_IMPORT_PATH'] = os.path.join(pyqt_path, 'qml')
  41. # Add `sys._MEIPASS` to `PATH` in order to ensure that `QtNetwork` can discover OpenSSL DLLs that might have been
  42. # collected there (i.e., when they were not shipped with the package, and were collected from an external location).
  43. if sys.platform.startswith('win'):
  44. prepend_path_to_environment_variable(sys._MEIPASS, 'PATH')
  45. # Qt bindings package installed via PyPI wheels typically ensures that its bundled Qt is relocatable, by creating
  46. # embedded `qt.conf` file during its initialization. This run-time generated qt.conf dynamically sets the Qt prefix
  47. # path to the package's Qt directory. For bindings packages that do not create embedded `qt.conf` during their
  48. # initialization (for example, conda-installed packages), try to perform this step ourselves.
  49. qt_rth_utils.create_embedded_qt_conf("PySide2", pyqt_path)
  50. _pyi_rthook()
  51. del _pyi_rthook