qt gui: be more resilient against import issues of QtMultimedia
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 "<frozen importlib._bootstrap>", line 1360, in _find_and_load File "<frozen importlib._bootstrap>", line 1331, in _find_and_load_unlocked File "<frozen importlib._bootstrap>", 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 <module> File "<frozen importlib._bootstrap>", line 1360, in _find_and_load File "<frozen importlib._bootstrap>", line 1331, in _find_and_load_unlocked File "<frozen importlib._bootstrap>", 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 <module> RuntimeError: PyQt6.QtMultimedia cannot import type '���d�⌂' from PyQt6.QtCore ```
This commit is contained in:
@@ -44,13 +44,19 @@ from PyQt6.QtCore import QObject, pyqtSignal, QTimer, Qt
|
|||||||
|
|
||||||
import PyQt6.QtCore as QtCore
|
import PyQt6.QtCore as QtCore
|
||||||
|
|
||||||
|
from electrum.logging import Logger, get_logger
|
||||||
|
_logger = get_logger(__name__)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
# Preload QtMultimedia at app start, if available.
|
# Preload QtMultimedia at app start, if available.
|
||||||
# We use QtMultimedia on some platforms for camera-handling, and
|
# 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)
|
# lazy-loading it later led to some crashes. Maybe due to bugs in PyQt. (see #7725)
|
||||||
from PyQt6.QtMultimedia import QMediaDevices; del QMediaDevices
|
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.
|
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"):
|
if sys.platform == "linux" and os.environ.get("APPIMAGE"):
|
||||||
# For AppImage, we default to xcb qt backend, for better support of older system.
|
# 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)
|
standardize_path)
|
||||||
from electrum.wallet import Wallet, Abstract_Wallet
|
from electrum.wallet import Wallet, Abstract_Wallet
|
||||||
from electrum.wallet_db import WalletRequiresSplit, WalletRequiresUpgrade, WalletUnfinished
|
from electrum.wallet_db import WalletRequiresSplit, WalletRequiresUpgrade, WalletUnfinished
|
||||||
from electrum.logging import Logger
|
|
||||||
from electrum.gui import BaseElectrumGui
|
from electrum.gui import BaseElectrumGui
|
||||||
from electrum.simple_config import SimpleConfig
|
from electrum.simple_config import SimpleConfig
|
||||||
from electrum.wizard import WizardViewState
|
from electrum.wizard import WizardViewState
|
||||||
|
|||||||
@@ -94,7 +94,8 @@ def find_system_cameras() -> Mapping[str, str]:
|
|||||||
if sys.platform == 'darwin' or sys.platform in ('windows', 'win32'):
|
if sys.platform == 'darwin' or sys.platform in ('windows', 'win32'):
|
||||||
try:
|
try:
|
||||||
from .qtmultimedia import find_system_cameras
|
from .qtmultimedia import find_system_cameras
|
||||||
except ImportError as e:
|
except (ImportError, RuntimeError) as e:
|
||||||
|
_logger.exception('error importing .qtmultimedia')
|
||||||
return {}
|
return {}
|
||||||
else:
|
else:
|
||||||
return find_system_cameras()
|
return find_system_cameras()
|
||||||
@@ -143,7 +144,7 @@ def _scan_qrcode_using_qtmultimedia(
|
|||||||
) -> None:
|
) -> None:
|
||||||
try:
|
try:
|
||||||
from .qtmultimedia import QrReaderCameraDialog, CameraError
|
from .qtmultimedia import QrReaderCameraDialog, CameraError
|
||||||
except ImportError as e:
|
except (ImportError, RuntimeError) as e:
|
||||||
icon = QMessageBox.Icon.Warning
|
icon = QMessageBox.Icon.Warning
|
||||||
title = _("QR Reader Error")
|
title = _("QR Reader Error")
|
||||||
message = _("QR reader failed to load. This may happen if "
|
message = _("QR reader failed to load. This may happen if "
|
||||||
|
|||||||
@@ -22,6 +22,11 @@
|
|||||||
# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||||
# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
# SOFTWARE.
|
# 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
|
from typing import Mapping
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user