From f366f3e7fbc6d13de57742495e80b86df46ec5d6 Mon Sep 17 00:00:00 2001 From: SomberNight Date: Fri, 13 Jun 2025 13:10:28 +0000 Subject: [PATCH] qt gui: be more resilient against import issues of QtMultimedia MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The user should still be able to open the Preferences dialog, despite the camera functionality being broken. see https://github.com/spesmilo/electrum/issues/9949 ``` 6.36 | E | gui.qt.exception_window.Exception_Hook | exception caught by crash reporter Traceback (most recent call last): File "electrum\gui\qt\main_window.py", line 2672, in settings_dialog File "electrum\gui\qt\settings_dialog.py", line 229, in __init__ File "electrum\gui\qt\qrreader\__init__.py", line 96, in find_system_cameras File "", line 1360, in _find_and_load File "", line 1331, in _find_and_load_unlocked File "", line 935, in _load_unlocked File "PyInstaller\loader\pyimod02_importers.py", line 450, in exec_module File "electrum\gui\qt\qrreader\qtmultimedia\__init__.py", line 28, in File "", line 1360, in _find_and_load File "", line 1331, in _find_and_load_unlocked File "", line 935, in _load_unlocked File "PyInstaller\loader\pyimod02_importers.py", line 450, in exec_module File "electrum\gui\qt\qrreader\qtmultimedia\camera_dialog.py", line 32, in RuntimeError: PyQt6.QtMultimedia cannot import type '���d�⌂' from PyQt6.QtCore ``` --- electrum/gui/qt/__init__.py | 9 +++++++-- electrum/gui/qt/qrreader/__init__.py | 5 +++-- electrum/gui/qt/qrreader/qtmultimedia/__init__.py | 5 +++++ 3 files changed, 15 insertions(+), 4 deletions(-) diff --git a/electrum/gui/qt/__init__.py b/electrum/gui/qt/__init__.py index bcadcfb5f..48a8c0ec9 100644 --- a/electrum/gui/qt/__init__.py +++ b/electrum/gui/qt/__init__.py @@ -44,13 +44,19 @@ from PyQt6.QtCore import QObject, pyqtSignal, QTimer, Qt import PyQt6.QtCore as QtCore +from electrum.logging import Logger, get_logger +_logger = get_logger(__name__) + try: # Preload QtMultimedia at app start, if available. # We use QtMultimedia on some platforms for camera-handling, and # lazy-loading it later led to some crashes. Maybe due to bugs in PyQt. (see #7725) from PyQt6.QtMultimedia import QMediaDevices; del QMediaDevices -except ImportError as e: +except (ImportError, RuntimeError) as e: + _logger.debug(f"failed to import optional dependency: PyQt6.QtMultimedia. exc={repr(e)}") pass # failure is ok; it is an optional dependency. +else: + _logger.debug(f"successfully preloaded optional dependency: PyQt6.QtMultimedia") if sys.platform == "linux" and os.environ.get("APPIMAGE"): # For AppImage, we default to xcb qt backend, for better support of older system. @@ -67,7 +73,6 @@ from electrum.util import (UserCancelled, profiler, send_exception_to_crash_repo standardize_path) from electrum.wallet import Wallet, Abstract_Wallet from electrum.wallet_db import WalletRequiresSplit, WalletRequiresUpgrade, WalletUnfinished -from electrum.logging import Logger from electrum.gui import BaseElectrumGui from electrum.simple_config import SimpleConfig from electrum.wizard import WizardViewState diff --git a/electrum/gui/qt/qrreader/__init__.py b/electrum/gui/qt/qrreader/__init__.py index 36191b299..367417632 100644 --- a/electrum/gui/qt/qrreader/__init__.py +++ b/electrum/gui/qt/qrreader/__init__.py @@ -94,7 +94,8 @@ def find_system_cameras() -> Mapping[str, str]: if sys.platform == 'darwin' or sys.platform in ('windows', 'win32'): try: from .qtmultimedia import find_system_cameras - except ImportError as e: + except (ImportError, RuntimeError) as e: + _logger.exception('error importing .qtmultimedia') return {} else: return find_system_cameras() @@ -143,7 +144,7 @@ def _scan_qrcode_using_qtmultimedia( ) -> None: try: from .qtmultimedia import QrReaderCameraDialog, CameraError - except ImportError as e: + except (ImportError, RuntimeError) as e: icon = QMessageBox.Icon.Warning title = _("QR Reader Error") message = _("QR reader failed to load. This may happen if " diff --git a/electrum/gui/qt/qrreader/qtmultimedia/__init__.py b/electrum/gui/qt/qrreader/qtmultimedia/__init__.py index e7db9400b..220f974a2 100644 --- a/electrum/gui/qt/qrreader/qtmultimedia/__init__.py +++ b/electrum/gui/qt/qrreader/qtmultimedia/__init__.py @@ -22,6 +22,11 @@ # ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN # CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE # SOFTWARE. +# +# ----- +# +# Note: This module is risky to import. At the very least, ImportError and +# RuntimeError needs to be handled at import time! from typing import Mapping