From 6270eae5c9dcc32868e74f25bb0c7d903dab2a29 Mon Sep 17 00:00:00 2001 From: Sander van Grieken Date: Fri, 14 Jul 2023 13:51:08 +0200 Subject: [PATCH] qml: port PyQt5 to PyQt6 --- electrum/gui/common_qt/plugins.py | 2 +- electrum/gui/default_lang.py | 2 +- electrum/gui/qml/__init__.py | 25 +++---- electrum/gui/qml/auth.py | 2 +- electrum/gui/qml/components/Constants.qml | 6 +- electrum/gui/qml/components/Wallets.qml | 7 +- .../controls/HistoryItemDelegate.qml | 2 +- .../components/controls/InvoiceDelegate.qml | 4 +- .../OnchainNetworkStatusIndicator.qml | 4 +- .../gui/qml/components/controls/QRScan.qml | 62 +++++++++------- electrum/gui/qml/components/main.qml | 71 ++++++++++--------- electrum/gui/qml/qeaddressdetails.py | 2 +- electrum/gui/qml/qeaddresslistmodel.py | 8 +-- electrum/gui/qml/qeapp.py | 37 +++++++--- electrum/gui/qml/qebip39recovery.py | 14 ++-- electrum/gui/qml/qebitcoin.py | 2 +- electrum/gui/qml/qechanneldetails.py | 8 +-- electrum/gui/qml/qechannellistmodel.py | 8 +-- electrum/gui/qml/qechannelopener.py | 2 +- electrum/gui/qml/qeconfig.py | 2 +- electrum/gui/qml/qedaemon.py | 8 +-- electrum/gui/qml/qefx.py | 2 +- electrum/gui/qml/qeinvoice.py | 12 ++-- electrum/gui/qml/qeinvoicelistmodel.py | 8 +-- electrum/gui/qml/qelnpaymentdetails.py | 2 +- electrum/gui/qml/qemodelfilter.py | 2 +- electrum/gui/qml/qenetwork.py | 2 +- electrum/gui/qml/qeqr.py | 8 +-- electrum/gui/qml/qerequestdetails.py | 8 +-- electrum/gui/qml/qeserverlistmodel.py | 8 +-- electrum/gui/qml/qeswaphelper.py | 8 +-- electrum/gui/qml/qetransactionlistmodel.py | 8 +-- electrum/gui/qml/qetxdetails.py | 2 +- electrum/gui/qml/qetxfinalizer.py | 2 +- electrum/gui/qml/qetypes.py | 2 +- electrum/gui/qml/qewallet.py | 2 +- electrum/gui/qml/qewizard.py | 2 +- electrum/gui/qml/util.py | 2 +- electrum/plugins/labels/qml.py | 2 +- electrum/plugins/trustedcoin/common_qt.py | 2 +- electrum/plugins/trustedcoin/qml.py | 1 + 41 files changed, 200 insertions(+), 163 deletions(-) diff --git a/electrum/gui/common_qt/plugins.py b/electrum/gui/common_qt/plugins.py index ba2189dd2..3403be027 100644 --- a/electrum/gui/common_qt/plugins.py +++ b/electrum/gui/common_qt/plugins.py @@ -1,4 +1,4 @@ -from PyQt5.QtCore import pyqtSignal, pyqtProperty, QObject +from PyQt6.QtCore import pyqtSignal, pyqtProperty, QObject # TODO: common code, Qt5/Qt6 mismatch! from electrum.logging import get_logger diff --git a/electrum/gui/default_lang.py b/electrum/gui/default_lang.py index e8a3e9b8e..aacf8112f 100644 --- a/electrum/gui/default_lang.py +++ b/electrum/gui/default_lang.py @@ -24,7 +24,7 @@ def get_default_language(*, gui_name: Optional[str] = None) -> str: name = QLocale.system().name() return name if name in languages else "en_UK" elif gui_name == "qml": - from PyQt5.QtCore import QLocale + from PyQt6.QtCore import QLocale # On Android QLocale does not return the system locale try: name = str(jLocale.getDefault().toString()) diff --git a/electrum/gui/qml/__init__.py b/electrum/gui/qml/__init__.py index 68c2ca40c..08894eb67 100644 --- a/electrum/gui/qml/__init__.py +++ b/electrum/gui/qml/__init__.py @@ -5,17 +5,17 @@ import threading from typing import TYPE_CHECKING try: - import PyQt5 + import PyQt6 except Exception: - sys.exit("Error: Could not import PyQt5 on Linux systems, you may try 'sudo apt-get install python3-pyqt5'") + sys.exit("Error: Could not import PyQt6 on Linux systems, you may try 'sudo apt-get install python3-pyqt6'") try: - import PyQt5.QtQml + import PyQt6.QtQml except Exception: - sys.exit("Error: Could not import PyQt5.QtQml on Linux systems, you may try 'sudo apt-get install python3-pyqt5.qtquick'") + sys.exit("Error: Could not import PyQt6.QtQml on Linux systems, you may try 'sudo apt-get install python3-pyqt6.qtquick'") -from PyQt5.QtCore import (Qt, QCoreApplication, QLocale, QTranslator, QTimer, QT_VERSION_STR, PYQT_VERSION_STR) -from PyQt5.QtGui import QGuiApplication +from PyQt6.QtCore import (Qt, QCoreApplication, QLocale, QTranslator, QTimer, QT_VERSION_STR, PYQT_VERSION_STR) +from PyQt6.QtGui import QGuiApplication from electrum.i18n import _ from electrum.plugin import run_hook @@ -40,7 +40,6 @@ class ElectrumTranslator(QTranslator): class ElectrumGui(BaseElectrumGui, Logger): - @profiler def __init__(self, config: 'SimpleConfig', daemon: 'Daemon', plugins: 'Plugins'): BaseElectrumGui.__init__(self, config=config, daemon=daemon, plugins=plugins) @@ -63,13 +62,11 @@ class ElectrumGui(BaseElectrumGui, Logger): # GC-ed when windows are closed #network.add_jobs([DebugMem([Abstract_Wallet, SPV, Synchronizer, # ElectrumWindow], interval=5)]) - QCoreApplication.setAttribute(Qt.AA_X11InitThreads) + if hasattr(Qt, "AA_ShareOpenGLContexts"): QCoreApplication.setAttribute(Qt.AA_ShareOpenGLContexts) if hasattr(QGuiApplication, 'setDesktopFileName'): QGuiApplication.setDesktopFileName('electrum.desktop') - if hasattr(Qt, "AA_EnableHighDpiScaling"): - QCoreApplication.setAttribute(Qt.AA_EnableHighDpiScaling) if "QT_QUICK_CONTROLS_STYLE" not in os.environ: os.environ["QT_QUICK_CONTROLS_STYLE"] = "Material" @@ -100,10 +97,14 @@ class ElectrumGui(BaseElectrumGui, Logger): return self.timer.start() - signal.signal(signal.SIGINT, lambda *args: self.stop()) + signal.signal(signal.SIGINT, lambda *args: self._handle_sigint()) self.logger.info('Entering main loop') - self.app.exec_() + self.app.exec() + + def _handle_sigint(self): + self.app.appController.wantClose = True + self.stop() def stop(self): self.logger.info('closing GUI') diff --git a/electrum/gui/qml/auth.py b/electrum/gui/qml/auth.py index 137e0fd31..3a7500815 100644 --- a/electrum/gui/qml/auth.py +++ b/electrum/gui/qml/auth.py @@ -1,6 +1,6 @@ from functools import wraps, partial -from PyQt5.QtCore import pyqtSignal, pyqtSlot +from PyQt6.QtCore import pyqtSignal, pyqtSlot from electrum.logging import get_logger diff --git a/electrum/gui/qml/components/Constants.qml b/electrum/gui/qml/components/Constants.qml index a701a9f1d..b9bdac1ff 100644 --- a/electrum/gui/qml/components/Constants.qml +++ b/electrum/gui/qml/components/Constants.qml @@ -1,8 +1,8 @@ -import QtQuick 2.6 -import QtQuick.Controls.Material 2.0 +import QtQuick +import QtQuick.Controls +import QtQuick.Controls.Material Item { - readonly property int paddingTiny: 4 //deprecated readonly property int paddingXXSmall: 4 readonly property int paddingXSmall: 6 readonly property int paddingSmall: 8 diff --git a/electrum/gui/qml/components/Wallets.qml b/electrum/gui/qml/components/Wallets.qml index b8dcf5f18..da762a1e3 100644 --- a/electrum/gui/qml/components/Wallets.qml +++ b/electrum/gui/qml/components/Wallets.qml @@ -27,12 +27,11 @@ Pane { ColumnLayout { id: rootLayout - width: parent.width - height: parent.height + anchors.fill: parent spacing: 0 ColumnLayout { - Layout.preferredWidth: parent.width + Layout.fillWidth: true Layout.margins: constants.paddingLarge Heading { @@ -41,7 +40,7 @@ Pane { Frame { id: detailsFrame - Layout.preferredWidth: parent.width + Layout.fillWidth: true Layout.fillHeight: true verticalPadding: 0 horizontalPadding: 0 diff --git a/electrum/gui/qml/components/controls/HistoryItemDelegate.qml b/electrum/gui/qml/components/controls/HistoryItemDelegate.qml index 3eec740b3..9d230536d 100644 --- a/electrum/gui/qml/components/controls/HistoryItemDelegate.qml +++ b/electrum/gui/qml/components/controls/HistoryItemDelegate.qml @@ -121,7 +121,7 @@ Item { visible: delegate.ListView.section == delegate.ListView.nextSection Layout.preferredWidth: parent.width * 2/3 Layout.alignment: Qt.AlignHCenter - Layout.preferredHeight: constants.paddingTiny + Layout.preferredHeight: constants.paddingXXSmall color: Material.background } diff --git a/electrum/gui/qml/components/controls/InvoiceDelegate.qml b/electrum/gui/qml/components/controls/InvoiceDelegate.qml index 18b3055d1..7ff214f68 100644 --- a/electrum/gui/qml/components/controls/InvoiceDelegate.qml +++ b/electrum/gui/qml/components/controls/InvoiceDelegate.qml @@ -31,7 +31,7 @@ ItemDelegate { Rectangle { Layout.columnSpan: 2 Layout.fillWidth: true - Layout.preferredHeight: constants.paddingTiny + Layout.preferredHeight: constants.paddingXXSmall color: 'transparent' } @@ -133,7 +133,7 @@ ItemDelegate { Rectangle { Layout.columnSpan: 2 Layout.fillWidth: true - Layout.preferredHeight: constants.paddingTiny + Layout.preferredHeight: constants.paddingXXSmall color: 'transparent' } diff --git a/electrum/gui/qml/components/controls/OnchainNetworkStatusIndicator.qml b/electrum/gui/qml/components/controls/OnchainNetworkStatusIndicator.qml index 7a575f4f4..739ef2ab3 100644 --- a/electrum/gui/qml/components/controls/OnchainNetworkStatusIndicator.qml +++ b/electrum/gui/qml/components/controls/OnchainNetworkStatusIndicator.qml @@ -13,7 +13,7 @@ Image { property bool proxy: connected && 'mode' in Network.proxy && Network.proxy.mode // ?: in order to keep this a binding.. - source: !connected + source: Qt.resolvedUrl(!connected ? '../../../icons/status_disconnected.png' : syncing ? '../../../icons/status_waiting.png' @@ -27,7 +27,7 @@ Image { : '../../../icons/status_connected_fork.png' : proxy ? '../../../icons/status_connected_proxy.png' - : '../../../icons/status_connected.png' + : '../../../icons/status_connected.png') states: [ diff --git a/electrum/gui/qml/components/controls/QRScan.qml b/electrum/gui/qml/components/controls/QRScan.qml index 75f8224c4..2ca1fbabe 100644 --- a/electrum/gui/qml/components/controls/QRScan.qml +++ b/electrum/gui/qml/components/controls/QRScan.qml @@ -1,6 +1,6 @@ import QtQuick 2.12 import QtQuick.Controls 2.0 -import QtMultimedia 5.6 +import QtMultimedia import org.electrum 1.0 @@ -25,7 +25,7 @@ Item { VideoOutput { id: vo anchors.fill: parent - source: camera + // source: camera fillMode: VideoOutput.PreserveAspectCrop Rectangle { @@ -114,31 +114,41 @@ Item { } } - Camera { - id: camera - deviceId: QtMultimedia.defaultCamera.deviceId - viewfinder.resolution: "640x480" - - focus { - focusMode: Camera.FocusContinuous - focusPointMode: Camera.FocusPointCustom - customFocusPoint: Qt.point(0.5, 0.5) - } + MediaDevices { + id: mediaDevices + } - function dumpstats() { - console.log(camera.viewfinder.resolution) - console.log(camera.viewfinder.minimumFrameRate) - console.log(camera.viewfinder.maximumFrameRate) - var resolutions = camera.supportedViewfinderResolutions() - resolutions.forEach(function(item, i) { - console.log('' + item.width + 'x' + item.height) - }) - // TODO - // pick a suitable resolution from the available resolutions - // problem: some cameras have no supportedViewfinderResolutions - // but still error out when an invalid resolution is set. - // 640x480 seems to be universally available, but this needs to - // be checked across a range of phone models. + CaptureSession { + videoOutput: VideoOutput + + camera: Camera { + id: camera + // deviceId: QtMultimedia.defaultCamera.deviceId + cameraDevice: mediaDevices.defaultVideoInput + // TODO QT6 + // viewfinder.resolution: "640x480" + + // focus { + // focusMode: Camera.FocusContinuous + // focusPointMode: Camera.FocusPointCustom + // customFocusPoint: Qt.point(0.5, 0.5) + // } + + function dumpstats() { + console.log(camera.viewfinder.resolution) + console.log(camera.viewfinder.minimumFrameRate) + console.log(camera.viewfinder.maximumFrameRate) + var resolutions = camera.supportedViewfinderResolutions() + resolutions.forEach(function(item, i) { + console.log('' + item.width + 'x' + item.height) + }) + // TODO + // pick a suitable resolution from the available resolutions + // problem: some cameras have no supportedViewfinderResolutions + // but still error out when an invalid resolution is set. + // 640x480 seems to be universally available, but this needs to + // be checked across a range of phone models. + } } } diff --git a/electrum/gui/qml/components/main.qml b/electrum/gui/qml/components/main.qml index fd2e59653..69f13da86 100644 --- a/electrum/gui/qml/components/main.qml +++ b/electrum/gui/qml/components/main.qml @@ -1,12 +1,13 @@ -import QtQuick 2.6 -import QtQuick.Layouts 1.0 -import QtQuick.Controls 2.3 -import QtQuick.Controls.Material 2.0 -import QtQuick.Controls.Material.impl 2.12 -import QtQuick.Window 2.15 +import QtQuick +import QtQuick.Layouts +import QtQuick.Controls +import QtQuick.Controls.Basic +import QtQuick.Controls.Material +import QtQuick.Controls.Material.impl +import QtQuick.Window -import QtQml 2.6 -import QtMultimedia 5.6 +import QtQml +import QtMultimedia import org.electrum 1.0 @@ -27,14 +28,13 @@ ApplicationWindow Material.accent: Material.LightBlue font.pixelSize: constants.fontSizeMedium - property Item constants: appconstants + property QtObject constants: appconstants Constants { id: appconstants } property alias stack: mainStackView property variant activeDialogs: [] - property bool _wantClose: false property var _exceptionDialog property QtObject appMenu: Menu { @@ -105,7 +105,8 @@ ApplicationWindow ColumnLayout { spacing: 0 - width: parent.width + anchors.left: parent.left + anchors.right: parent.right height: toolbar.height RowLayout { @@ -171,7 +172,6 @@ ApplicationWindow RowLayout { id: statusIconsLayout anchors.verticalCenter: parent.verticalCenter - Item { Layout.preferredWidth: constants.paddingLarge Layout.preferredHeight: 1 @@ -207,9 +207,12 @@ ApplicationWindow } } - WalletSummary { - id: walletSummary - Layout.preferredWidth: app.width + // hack to force relayout of toolbar + // since qt6 watchOnlyIndicator.visible doesn't trigger relayout(?) + Item { + Layout.preferredHeight: 1 + Layout.topMargin: -1 + Layout.preferredWidth: watchOnlyIndicator.visible ? app.width : 1 } } } @@ -218,7 +221,9 @@ ApplicationWindow id: mainStackView width: parent.width height: keyboardFreeZone.height - header.height - initialItem: Qt.resolvedUrl('WalletMainView.qml') + initialItem: Component { + WalletMainView {} + } function getRoot() { return mainStackView.get(0) @@ -454,7 +459,13 @@ ApplicationWindow } } - onClosing: { + onClosing: (close) => { + if (AppController.wantClose) { + // destroy most GUI components so that we don't dump so many null reference warnings on exit + app.header.visible = false + mainStackView.clear() + return + } if (activeDialogs.length > 0) { var activeDialog = activeDialogs[activeDialogs.length - 1] if (activeDialog.allowClose) { @@ -469,22 +480,16 @@ ApplicationWindow close.accepted = false stack.pop() } else { - // destroy most GUI components so that we don't dump so many null reference warnings on exit - if (app._wantClose) { - app.header.visible = false - mainStackView.clear() - } else { - var dialog = app.messageDialog.createObject(app, { - title: qsTr('Close Electrum?'), - yesno: true - }) - dialog.accepted.connect(function() { - app._wantClose = true - app.close() - }) - dialog.open() - close.accepted = false - } + var dialog = app.messageDialog.createObject(app, { + title: qsTr('Close Electrum?'), + yesno: true + }) + dialog.accepted.connect(function() { + AppController.wantClose = true + app.close() + }) + dialog.open() + close.accepted = false } } diff --git a/electrum/gui/qml/qeaddressdetails.py b/electrum/gui/qml/qeaddressdetails.py index f09cbb630..1c399cddc 100644 --- a/electrum/gui/qml/qeaddressdetails.py +++ b/electrum/gui/qml/qeaddressdetails.py @@ -1,4 +1,4 @@ -from PyQt5.QtCore import pyqtProperty, pyqtSignal, pyqtSlot, QObject +from PyQt6.QtCore import pyqtProperty, pyqtSignal, pyqtSlot, QObject from electrum.logging import get_logger diff --git a/electrum/gui/qml/qeaddresslistmodel.py b/electrum/gui/qml/qeaddresslistmodel.py index d87b027ee..3fee9350b 100644 --- a/electrum/gui/qml/qeaddresslistmodel.py +++ b/electrum/gui/qml/qeaddresslistmodel.py @@ -1,7 +1,7 @@ from typing import TYPE_CHECKING, List -from PyQt5.QtCore import pyqtSlot, QSortFilterProxyModel, pyqtSignal, pyqtProperty -from PyQt5.QtCore import Qt, QAbstractListModel, QModelIndex +from PyQt6.QtCore import pyqtSlot, QSortFilterProxyModel, pyqtSignal, pyqtProperty +from PyQt6.QtCore import Qt, QAbstractListModel, QModelIndex from electrum.logging import get_logger from electrum.util import Satoshis @@ -107,7 +107,7 @@ class QEAddressCoinListModel(QAbstractListModel): # define listmodel rolemap _ROLE_NAMES=('type', 'addridx', 'address', 'label', 'balance', 'numtx', 'held', 'height', 'amount', 'outpoint', 'short_outpoint', 'short_id', 'txid') - _ROLE_KEYS = range(Qt.UserRole, Qt.UserRole + len(_ROLE_NAMES)) + _ROLE_KEYS = range(Qt.ItemDataRole.UserRole, Qt.ItemDataRole.UserRole + len(_ROLE_NAMES)) _ROLE_MAP = dict(zip(_ROLE_KEYS, [bytearray(x.encode()) for x in _ROLE_NAMES])) _ROLE_RMAP = dict(zip(_ROLE_NAMES, _ROLE_KEYS)) @@ -128,7 +128,7 @@ class QEAddressCoinListModel(QAbstractListModel): def data(self, index, role): address = self._items[index.row()] - role_index = role - Qt.UserRole + role_index = role - Qt.ItemDataRole.UserRole try: value = address[self._ROLE_NAMES[role_index]] except KeyError: diff --git a/electrum/gui/qml/qeapp.py b/electrum/gui/qml/qeapp.py index a28522f3e..37805f340 100644 --- a/electrum/gui/qml/qeapp.py +++ b/electrum/gui/qml/qeapp.py @@ -7,10 +7,10 @@ import html import threading from typing import TYPE_CHECKING, Set -from PyQt5.QtCore import (pyqtSlot, pyqtSignal, pyqtProperty, QObject, +from PyQt6.QtCore import (pyqtSlot, pyqtSignal, pyqtProperty, QObject, qInstallMessageHandler, QTimer, QSortFilterProxyModel) -from PyQt5.QtGui import QGuiApplication, QFontDatabase -from PyQt5.QtQml import qmlRegisterType, qmlRegisterUncreatableType, QQmlApplicationEngine +from PyQt6.QtGui import QGuiApplication, QFontDatabase +from PyQt6.QtQml import qmlRegisterType, qmlRegisterUncreatableType, QQmlApplicationEngine from electrum import version, constants from electrum.i18n import _ @@ -69,6 +69,7 @@ class QEAppController(BaseCrashReporter, QObject): sendingBugreportSuccess = pyqtSignal(str) sendingBugreportFailure = pyqtSignal(str) secureWindowChanged = pyqtSignal() + wantCloseChanged = pyqtSignal() def __init__(self, qeapp: 'ElectrumQmlApplication', qedaemon: 'QEDaemon', plugins: 'Plugins'): BaseCrashReporter.__init__(self, None, None, None) @@ -100,6 +101,8 @@ class QEAppController(BaseCrashReporter, QObject): if self.isAndroid(): self.bindIntent() + self._want_close = False + def on_wallet_loaded(self): qewallet = self._qedaemon.currentWallet if not qewallet: @@ -179,6 +182,16 @@ class QEAppController(BaseCrashReporter, QObject): if self._intent: self.on_new_intent(self._intent) + @pyqtProperty(bool, notify=wantCloseChanged) + def wantClose(self): + return self._want_close + + @wantClose.setter + def wantClose(self, want_close): + if want_close != self._want_close: + self._want_close = want_close + self.wantCloseChanged.emit() + @pyqtSlot(str, str) def doShare(self, data, title): if not self.isAndroid(): @@ -330,6 +343,13 @@ class ElectrumQmlApplication(QGuiApplication): ElectrumQmlApplication._daemon = daemon + # TODO QT6 order of declaration is important now? + qmlRegisterType(QEAmount, 'org.electrum', 1, 0, 'Amount') + qmlRegisterType(QENewWalletWizard, 'org.electrum', 1, 0, 'QNewWalletWizard') + qmlRegisterType(QEServerConnectWizard, 'org.electrum', 1, 0, 'QServerConnectWizard') + qmlRegisterType(QEFilterProxyModel, 'org.electrum', 1, 0, 'FilterProxyModel') + qmlRegisterType(QSortFilterProxyModel, 'org.electrum', 1, 0, 'QSortFilterProxyModel') + qmlRegisterType(QEWallet, 'org.electrum', 1, 0, 'Wallet') qmlRegisterType(QEBitcoin, 'org.electrum', 1, 0, 'Bitcoin') qmlRegisterType(QEQRParser, 'org.electrum', 1, 0, 'QRParser') @@ -349,11 +369,12 @@ class ElectrumQmlApplication(QGuiApplication): qmlRegisterType(QETxCanceller, 'org.electrum', 1, 0, 'TxCanceller') qmlRegisterType(QEBip39RecoveryListModel, 'org.electrum', 1, 0, 'Bip39RecoveryListModel') - qmlRegisterUncreatableType(QEAmount, 'org.electrum', 1, 0, 'Amount', 'Amount can only be used as property') - qmlRegisterUncreatableType(QENewWalletWizard, 'org.electrum', 1, 0, 'QNewWalletWizard', 'QNewWalletWizard can only be used as property') - qmlRegisterUncreatableType(QEServerConnectWizard, 'org.electrum', 1, 0, 'QServerConnectWizard', 'QServerConnectWizard can only be used as property') - qmlRegisterUncreatableType(QEFilterProxyModel, 'org.electrum', 1, 0, 'FilterProxyModel', 'FilterProxyModel can only be used as property') - qmlRegisterUncreatableType(QSortFilterProxyModel, 'org.electrum', 1, 0, 'QSortFilterProxyModel', 'QSortFilterProxyModel can only be used as property') + # TODO QT6 + # qmlRegisterUncreatableType(QEAmount, 'org.electrum', 1, 0, 'Amount', 'Amount can only be used as property') + # qmlRegisterUncreatableType(QENewWalletWizard, 'org.electrum', 1, 0, 'QNewWalletWizard', 'QNewWalletWizard can only be used as property') + # qmlRegisterUncreatableType(QEServerConnectWizard, 'org.electrum', 1, 0, 'QServerConnectWizard', 'QServerConnectWizard can only be used as property') + # qmlRegisterUncreatableType(QEFilterProxyModel, 'org.electrum', 1, 0, 'FilterProxyModel', 'FilterProxyModel can only be used as property') + # qmlRegisterUncreatableType(QSortFilterProxyModel, 'org.electrum', 1, 0, 'QSortFilterProxyModel', 'QSortFilterProxyModel can only be used as property') self.engine = QQmlApplicationEngine(parent=self) diff --git a/electrum/gui/qml/qebip39recovery.py b/electrum/gui/qml/qebip39recovery.py index 713bfad27..90d1831f8 100644 --- a/electrum/gui/qml/qebip39recovery.py +++ b/electrum/gui/qml/qebip39recovery.py @@ -1,8 +1,9 @@ import asyncio import concurrent +from enum import IntEnum -from PyQt5.QtCore import pyqtProperty, pyqtSignal, pyqtSlot -from PyQt5.QtCore import Qt, QAbstractListModel, QModelIndex, Q_ENUMS +from PyQt6.QtCore import pyqtProperty, pyqtSignal, pyqtSlot, pyqtEnum +from PyQt6.QtCore import Qt, QAbstractListModel, QModelIndex from electrum import Network, keystore from electrum.bip32 import BIP32Node @@ -15,21 +16,20 @@ from .util import TaskThread class QEBip39RecoveryListModel(QAbstractListModel): _logger = get_logger(__name__) - class State: + @pyqtEnum + class State(IntEnum): Idle = -1 Scanning = 0 Success = 1 Failed = 2 Cancelled = 3 - Q_ENUMS(State) - recoveryFailed = pyqtSignal() stateChanged = pyqtSignal() # define listmodel rolemap _ROLE_NAMES=('description', 'derivation_path', 'script_type') - _ROLE_KEYS = range(Qt.UserRole, Qt.UserRole + len(_ROLE_NAMES)) + _ROLE_KEYS = range(Qt.ItemDataRole.UserRole, Qt.ItemDataRole.UserRole + len(_ROLE_NAMES)) _ROLE_MAP = dict(zip(_ROLE_KEYS, [bytearray(x.encode()) for x in _ROLE_NAMES])) def __init__(self, config, parent=None): @@ -47,7 +47,7 @@ class QEBip39RecoveryListModel(QAbstractListModel): def data(self, index, role): account = self._accounts[index.row()] - role_index = role - Qt.UserRole + role_index = role - Qt.ItemDataRole.UserRole value = account[self._ROLE_NAMES[role_index]] if isinstance(value, (bool, list, int, str)) or value is None: return value diff --git a/electrum/gui/qml/qebitcoin.py b/electrum/gui/qml/qebitcoin.py index f63e752fd..3c4b2264b 100644 --- a/electrum/gui/qml/qebitcoin.py +++ b/electrum/gui/qml/qebitcoin.py @@ -1,6 +1,6 @@ import asyncio -from PyQt5.QtCore import pyqtProperty, pyqtSignal, pyqtSlot, QObject +from PyQt6.QtCore import pyqtProperty, pyqtSignal, pyqtSlot, QObject from electrum import mnemonic from electrum import keystore diff --git a/electrum/gui/qml/qechanneldetails.py b/electrum/gui/qml/qechanneldetails.py index 58d5857e7..cf1adb97d 100644 --- a/electrum/gui/qml/qechanneldetails.py +++ b/electrum/gui/qml/qechanneldetails.py @@ -1,6 +1,7 @@ import threading +from enum import IntEnum -from PyQt5.QtCore import pyqtProperty, pyqtSignal, pyqtSlot, QObject, Q_ENUMS +from PyQt6.QtCore import pyqtProperty, pyqtSignal, pyqtSlot, QObject, pyqtEnum from electrum.i18n import _ from electrum.gui import messages @@ -17,12 +18,11 @@ from .util import QtEventListener, event_listener class QEChannelDetails(AuthMixin, QObject, QtEventListener): _logger = get_logger(__name__) - class State: # subset, only ones we currently need in UI + @pyqtEnum + class State(IntEnum): # subset, only ones we currently need in UI Closed = ChannelState.CLOSED Redeemed = ChannelState.REDEEMED - Q_ENUMS(State) - channelChanged = pyqtSignal() channelCloseSuccess = pyqtSignal() channelCloseFailed = pyqtSignal([str], arguments=['message']) diff --git a/electrum/gui/qml/qechannellistmodel.py b/electrum/gui/qml/qechannellistmodel.py index ccf69ef28..b3bf4586e 100644 --- a/electrum/gui/qml/qechannellistmodel.py +++ b/electrum/gui/qml/qechannellistmodel.py @@ -1,5 +1,5 @@ -from PyQt5.QtCore import Qt, QAbstractListModel, QModelIndex -from PyQt5.QtCore import pyqtProperty, pyqtSignal, pyqtSlot +from PyQt6.QtCore import Qt, QAbstractListModel, QModelIndex +from PyQt6.QtCore import pyqtProperty, pyqtSignal, pyqtSlot from electrum.lnchannel import ChannelState from electrum.lnutil import LOCAL, REMOTE @@ -20,7 +20,7 @@ class QEChannelListModel(QAbstractListModel, QtEventListener): 'can_receive', 'l_csv_delay', 'r_csv_delay', 'send_frozen', 'receive_frozen', 'type', 'node_id', 'node_alias', 'short_cid', 'funding_tx', 'is_trampoline', 'is_backup', 'is_imported', 'local_capacity', 'remote_capacity') - _ROLE_KEYS = range(Qt.UserRole, Qt.UserRole + len(_ROLE_NAMES)) + _ROLE_KEYS = range(Qt.ItemDataRole.UserRole, Qt.ItemDataRole.UserRole + len(_ROLE_NAMES)) _ROLE_MAP = dict(zip(_ROLE_KEYS, [bytearray(x.encode()) for x in _ROLE_NAMES])) _ROLE_RMAP = dict(zip(_ROLE_NAMES, _ROLE_KEYS)) @@ -70,7 +70,7 @@ class QEChannelListModel(QAbstractListModel, QtEventListener): def data(self, index, role): tx = self._channels[index.row()] - role_index = role - Qt.UserRole + role_index = role - Qt.ItemDataRole.UserRole value = tx[self._ROLE_NAMES[role_index]] if isinstance(value, (bool, list, int, str, QEAmount)) or value is None: return value diff --git a/electrum/gui/qml/qechannelopener.py b/electrum/gui/qml/qechannelopener.py index f8f6f7231..d5c2fd327 100644 --- a/electrum/gui/qml/qechannelopener.py +++ b/electrum/gui/qml/qechannelopener.py @@ -3,7 +3,7 @@ from concurrent.futures import CancelledError from asyncio.exceptions import TimeoutError from typing import TYPE_CHECKING, Optional -from PyQt5.QtCore import pyqtProperty, pyqtSignal, pyqtSlot, QObject +from PyQt6.QtCore import pyqtProperty, pyqtSignal, pyqtSlot, QObject from electrum.i18n import _ from electrum.gui import messages diff --git a/electrum/gui/qml/qeconfig.py b/electrum/gui/qml/qeconfig.py index c34796e27..99ebc1d41 100644 --- a/electrum/gui/qml/qeconfig.py +++ b/electrum/gui/qml/qeconfig.py @@ -2,7 +2,7 @@ import copy from decimal import Decimal from typing import TYPE_CHECKING -from PyQt5.QtCore import pyqtProperty, pyqtSignal, pyqtSlot, QObject, QRegularExpression +from PyQt6.QtCore import pyqtProperty, pyqtSignal, pyqtSlot, QObject, QRegularExpression from electrum.bitcoin import TOTAL_COIN_SUPPLY_LIMIT_IN_BTC from electrum.i18n import set_language, languages diff --git a/electrum/gui/qml/qedaemon.py b/electrum/gui/qml/qedaemon.py index cc448171e..6b44933cc 100644 --- a/electrum/gui/qml/qedaemon.py +++ b/electrum/gui/qml/qedaemon.py @@ -3,8 +3,8 @@ import os import threading from typing import TYPE_CHECKING -from PyQt5.QtCore import Qt, QAbstractListModel, QModelIndex -from PyQt5.QtCore import pyqtProperty, pyqtSignal, pyqtSlot, QObject +from PyQt6.QtCore import Qt, QAbstractListModel, QModelIndex +from PyQt6.QtCore import pyqtProperty, pyqtSignal, pyqtSlot, QObject from electrum.i18n import _ from electrum.logging import get_logger @@ -32,7 +32,7 @@ class QEWalletListModel(QAbstractListModel): # define listmodel rolemap _ROLE_NAMES= ('name', 'path', 'active') - _ROLE_KEYS = range(Qt.UserRole, Qt.UserRole + len(_ROLE_NAMES)) + _ROLE_KEYS = range(Qt.ItemDataRole.UserRole, Qt.ItemDataRole.UserRole + len(_ROLE_NAMES)) _ROLE_MAP = dict(zip(_ROLE_KEYS, [bytearray(x.encode()) for x in _ROLE_NAMES])) def __init__(self, daemon, parent=None): @@ -49,7 +49,7 @@ class QEWalletListModel(QAbstractListModel): def data(self, index, role): (wallet_name, wallet_path) = self._wallets[index.row()] - role_index = role - Qt.UserRole + role_index = role - Qt.ItemDataRole.UserRole role_name = self._ROLE_NAMES[role_index] if role_name == 'name': return wallet_name diff --git a/electrum/gui/qml/qefx.py b/electrum/gui/qml/qefx.py index 22e1ecbaa..fcb7316da 100644 --- a/electrum/gui/qml/qefx.py +++ b/electrum/gui/qml/qefx.py @@ -1,7 +1,7 @@ from datetime import datetime from decimal import Decimal -from PyQt5.QtCore import pyqtProperty, pyqtSignal, pyqtSlot, QObject, QRegularExpression +from PyQt6.QtCore import pyqtProperty, pyqtSignal, pyqtSlot, QObject, QRegularExpression from electrum.bitcoin import COIN from electrum.exchange_rate import FxThread diff --git a/electrum/gui/qml/qeinvoice.py b/electrum/gui/qml/qeinvoice.py index 3a4d9df47..6d1580a0a 100644 --- a/electrum/gui/qml/qeinvoice.py +++ b/electrum/gui/qml/qeinvoice.py @@ -1,7 +1,8 @@ +from enum import IntEnum from typing import Optional, Dict, Any from urllib.parse import urlparse -from PyQt5.QtCore import pyqtProperty, pyqtSignal, pyqtSlot, QObject, Q_ENUMS, QTimer +from PyQt6.QtCore import pyqtProperty, pyqtSignal, pyqtSlot, QObject, pyqtEnum, QTimer from electrum.i18n import _ from electrum.logging import get_logger @@ -18,13 +19,15 @@ from .util import status_update_timer_interval, QtEventListener, event_listener class QEInvoice(QObject, QtEventListener): - class Type: + @pyqtEnum + class Type(IntEnum): Invalid = -1 OnchainInvoice = 0 LightningInvoice = 1 LNURLPayRequest = 2 - class Status: + @pyqtEnum + class Status(IntEnum): Unpaid = PR_UNPAID Expired = PR_EXPIRED Unknown = PR_UNKNOWN @@ -34,9 +37,6 @@ class QEInvoice(QObject, QtEventListener): Routing = PR_ROUTING Unconfirmed = PR_UNCONFIRMED - Q_ENUMS(Type) - Q_ENUMS(Status) - _logger = get_logger(__name__) invoiceChanged = pyqtSignal() diff --git a/electrum/gui/qml/qeinvoicelistmodel.py b/electrum/gui/qml/qeinvoicelistmodel.py index d946cb97f..e97611e0d 100644 --- a/electrum/gui/qml/qeinvoicelistmodel.py +++ b/electrum/gui/qml/qeinvoicelistmodel.py @@ -1,8 +1,8 @@ from abc import abstractmethod from typing import TYPE_CHECKING, List, Dict, Any -from PyQt5.QtCore import pyqtSlot, QTimer -from PyQt5.QtCore import Qt, QAbstractListModel, QModelIndex +from PyQt6.QtCore import pyqtSlot, QTimer +from PyQt6.QtCore import Qt, QAbstractListModel, QModelIndex from electrum.logging import get_logger from electrum.util import Satoshis, format_time @@ -22,7 +22,7 @@ class QEAbstractInvoiceListModel(QAbstractListModel): _ROLE_NAMES=('key', 'is_lightning', 'timestamp', 'date', 'message', 'amount', 'status', 'status_str', 'address', 'expiry', 'type', 'onchain_fallback', 'lightning_invoice') - _ROLE_KEYS = range(Qt.UserRole, Qt.UserRole + len(_ROLE_NAMES)) + _ROLE_KEYS = range(Qt.ItemDataRole.UserRole, Qt.ItemDataRole.UserRole + len(_ROLE_NAMES)) _ROLE_MAP = dict(zip(_ROLE_KEYS, [bytearray(x.encode()) for x in _ROLE_NAMES])) _ROLE_RMAP = dict(zip(_ROLE_NAMES, _ROLE_KEYS)) @@ -49,7 +49,7 @@ class QEAbstractInvoiceListModel(QAbstractListModel): def data(self, index, role): invoice = self._invoices[index.row()] - role_index = role - Qt.UserRole + role_index = role - Qt.ItemDataRole.UserRole value = invoice[self._ROLE_NAMES[role_index]] if isinstance(value, (bool, list, int, str, QEAmount)) or value is None: diff --git a/electrum/gui/qml/qelnpaymentdetails.py b/electrum/gui/qml/qelnpaymentdetails.py index 545f7877c..190a0ef06 100644 --- a/electrum/gui/qml/qelnpaymentdetails.py +++ b/electrum/gui/qml/qelnpaymentdetails.py @@ -1,4 +1,4 @@ -from PyQt5.QtCore import pyqtProperty, pyqtSignal, pyqtSlot, QObject +from PyQt6.QtCore import pyqtProperty, pyqtSignal, pyqtSlot, QObject from electrum.logging import get_logger from electrum.util import bfh, format_time diff --git a/electrum/gui/qml/qemodelfilter.py b/electrum/gui/qml/qemodelfilter.py index d5bd75af2..e6bbcdaad 100644 --- a/electrum/gui/qml/qemodelfilter.py +++ b/electrum/gui/qml/qemodelfilter.py @@ -1,4 +1,4 @@ -from PyQt5.QtCore import pyqtSignal, pyqtProperty, QSortFilterProxyModel, QModelIndex, pyqtSlot +from PyQt6.QtCore import pyqtSignal, pyqtProperty, QSortFilterProxyModel, QModelIndex, pyqtSlot from electrum.logging import get_logger diff --git a/electrum/gui/qml/qenetwork.py b/electrum/gui/qml/qenetwork.py index 1cfeb3c58..93d9db7af 100644 --- a/electrum/gui/qml/qenetwork.py +++ b/electrum/gui/qml/qenetwork.py @@ -1,6 +1,6 @@ from typing import TYPE_CHECKING -from PyQt5.QtCore import pyqtProperty, pyqtSignal, QObject +from PyQt6.QtCore import pyqtProperty, pyqtSignal, QObject from electrum.logging import get_logger from electrum import constants diff --git a/electrum/gui/qml/qeqr.py b/electrum/gui/qml/qeqr.py index 1eaa90306..a102461bd 100644 --- a/electrum/gui/qml/qeqr.py +++ b/electrum/gui/qml/qeqr.py @@ -7,9 +7,9 @@ import urllib from PIL import Image, ImageQt -from PyQt5.QtCore import pyqtProperty, pyqtSignal, pyqtSlot, QObject, QRect, QPoint -from PyQt5.QtGui import QImage, QColor -from PyQt5.QtQuick import QQuickImageProvider +from PyQt6.QtCore import pyqtProperty, pyqtSignal, pyqtSlot, QObject, QRect, QPoint +from PyQt6.QtGui import QImage, QColor +from PyQt6.QtQuick import QQuickImageProvider from electrum.logging import get_logger from electrum.qrreader import get_qr_reader @@ -123,7 +123,7 @@ class QEQRParser(QObject): class QEQRImageProvider(QQuickImageProvider): def __init__(self, max_size, parent=None): - super().__init__(QQuickImageProvider.Image) + super().__init__(QQuickImageProvider.ImageType.Image) self._max_size = max_size self.qimg = None diff --git a/electrum/gui/qml/qerequestdetails.py b/electrum/gui/qml/qerequestdetails.py index 9d07d54e1..ef259ec2a 100644 --- a/electrum/gui/qml/qerequestdetails.py +++ b/electrum/gui/qml/qerequestdetails.py @@ -1,6 +1,7 @@ +from enum import IntEnum from typing import Optional -from PyQt5.QtCore import pyqtProperty, pyqtSignal, pyqtSlot, QObject, QTimer, Q_ENUMS +from PyQt6.QtCore import pyqtProperty, pyqtSignal, pyqtSlot, QObject, QTimer, pyqtEnum from electrum.logging import get_logger from electrum.invoices import (PR_UNPAID, PR_EXPIRED, PR_UNKNOWN, PR_PAID, PR_INFLIGHT, @@ -13,7 +14,8 @@ from .util import QtEventListener, event_listener, status_update_timer_interval class QERequestDetails(QObject, QtEventListener): - class Status: + @pyqtEnum + class Status(IntEnum): Unpaid = PR_UNPAID Expired = PR_EXPIRED Unknown = PR_UNKNOWN @@ -23,8 +25,6 @@ class QERequestDetails(QObject, QtEventListener): Routing = PR_ROUTING Unconfirmed = PR_UNCONFIRMED - Q_ENUMS(Status) - _logger = get_logger(__name__) detailsChanged = pyqtSignal() # generic request properties changed signal diff --git a/electrum/gui/qml/qeserverlistmodel.py b/electrum/gui/qml/qeserverlistmodel.py index 040c0efea..4863a3789 100644 --- a/electrum/gui/qml/qeserverlistmodel.py +++ b/electrum/gui/qml/qeserverlistmodel.py @@ -1,5 +1,5 @@ -from PyQt5.QtCore import pyqtProperty, pyqtSignal, pyqtSlot -from PyQt5.QtCore import Qt, QAbstractListModel, QModelIndex +from PyQt6.QtCore import pyqtProperty, pyqtSignal, pyqtSlot +from PyQt6.QtCore import Qt, QAbstractListModel, QModelIndex from electrum.logging import get_logger from electrum.util import Satoshis @@ -14,7 +14,7 @@ class QEServerListModel(QAbstractListModel, QtEventListener): # define listmodel rolemap _ROLE_NAMES=('name', 'address', 'is_connected', 'is_primary', 'is_tor', 'chain', 'height') - _ROLE_KEYS = range(Qt.UserRole, Qt.UserRole + len(_ROLE_NAMES)) + _ROLE_KEYS = range(Qt.ItemDataRole.UserRole, Qt.ItemDataRole.UserRole + len(_ROLE_NAMES)) _ROLE_MAP = dict(zip(_ROLE_KEYS, [bytearray(x.encode()) for x in _ROLE_NAMES])) _ROLE_RMAP = dict(zip(_ROLE_NAMES, _ROLE_KEYS)) @@ -52,7 +52,7 @@ class QEServerListModel(QAbstractListModel, QtEventListener): def data(self, index, role): server = self._servers[index.row()] - role_index = role - Qt.UserRole + role_index = role - Qt.ItemDataRole.UserRole value = server[self._ROLE_NAMES[role_index]] if isinstance(value, (bool, list, int, str)) or value is None: diff --git a/electrum/gui/qml/qeswaphelper.py b/electrum/gui/qml/qeswaphelper.py index 846401fcb..78c4b0f04 100644 --- a/electrum/gui/qml/qeswaphelper.py +++ b/electrum/gui/qml/qeswaphelper.py @@ -1,9 +1,10 @@ import asyncio import concurrent import threading +from enum import IntEnum from typing import Union -from PyQt5.QtCore import pyqtProperty, pyqtSignal, pyqtSlot, QObject, QTimer, Q_ENUMS +from PyQt6.QtCore import pyqtProperty, pyqtSignal, pyqtSlot, QObject, QTimer, pyqtEnum from electrum.i18n import _ from electrum.bitcoin import DummyAddress @@ -23,7 +24,8 @@ class InvalidSwapParameters(Exception): pass class QESwapHelper(AuthMixin, QObject, QtEventListener): _logger = get_logger(__name__) - class State: + @pyqtEnum + class State(IntEnum): Initialized = 0 ServiceReady = 1 Started = 2 @@ -31,8 +33,6 @@ class QESwapHelper(AuthMixin, QObject, QtEventListener): Success = 4 Cancelled = 5 - Q_ENUMS(State) - confirm = pyqtSignal([str], arguments=['message']) error = pyqtSignal([str], arguments=['message']) diff --git a/electrum/gui/qml/qetransactionlistmodel.py b/electrum/gui/qml/qetransactionlistmodel.py index 3ecb40e7c..52250c8d4 100644 --- a/electrum/gui/qml/qetransactionlistmodel.py +++ b/electrum/gui/qml/qetransactionlistmodel.py @@ -1,8 +1,8 @@ from datetime import datetime, timedelta from typing import TYPE_CHECKING, Dict, Any -from PyQt5.QtCore import pyqtProperty, pyqtSignal, pyqtSlot -from PyQt5.QtCore import Qt, QAbstractListModel, QModelIndex +from PyQt6.QtCore import pyqtProperty, pyqtSignal, pyqtSlot +from PyQt6.QtCore import Qt, QAbstractListModel, QModelIndex from electrum.logging import get_logger from electrum.util import Satoshis, TxMinedInfo @@ -22,7 +22,7 @@ class QETransactionListModel(QAbstractListModel, QtEventListener): _ROLE_NAMES=('txid', 'fee_sat', 'height', 'confirmations', 'timestamp', 'monotonic_timestamp', 'incoming', 'value', 'date', 'label', 'txpos_in_block', 'fee', 'inputs', 'outputs', 'section', 'type', 'lightning', 'payment_hash', 'key', 'complete') - _ROLE_KEYS = range(Qt.UserRole, Qt.UserRole + len(_ROLE_NAMES)) + _ROLE_KEYS = range(Qt.ItemDataRole.UserRole, Qt.ItemDataRole.UserRole + len(_ROLE_NAMES)) _ROLE_MAP = dict(zip(_ROLE_KEYS, [bytearray(x.encode()) for x in _ROLE_NAMES])) _ROLE_RMAP = dict(zip(_ROLE_NAMES, _ROLE_KEYS)) @@ -95,7 +95,7 @@ class QETransactionListModel(QAbstractListModel, QtEventListener): def data(self, index, role): tx = self.tx_history[index.row()] - role_index = role - Qt.UserRole + role_index = role - Qt.ItemDataRole.UserRole try: value = tx[self._ROLE_NAMES[role_index]] diff --git a/electrum/gui/qml/qetxdetails.py b/electrum/gui/qml/qetxdetails.py index 26c71e35a..c2e7775da 100644 --- a/electrum/gui/qml/qetxdetails.py +++ b/electrum/gui/qml/qetxdetails.py @@ -1,6 +1,6 @@ from typing import Optional -from PyQt5.QtCore import pyqtProperty, pyqtSignal, pyqtSlot, QObject +from PyQt6.QtCore import pyqtProperty, pyqtSignal, pyqtSlot, QObject from electrum.i18n import _ from electrum.logging import get_logger diff --git a/electrum/gui/qml/qetxfinalizer.py b/electrum/gui/qml/qetxfinalizer.py index 6e2fd3f3d..e4d12ef6c 100644 --- a/electrum/gui/qml/qetxfinalizer.py +++ b/electrum/gui/qml/qetxfinalizer.py @@ -2,7 +2,7 @@ from decimal import Decimal from typing import Optional, TYPE_CHECKING from functools import partial -from PyQt5.QtCore import pyqtProperty, pyqtSignal, pyqtSlot, QObject +from PyQt6.QtCore import pyqtProperty, pyqtSignal, pyqtSlot, QObject from electrum.logging import get_logger from electrum.i18n import _ diff --git a/electrum/gui/qml/qetypes.py b/electrum/gui/qml/qetypes.py index d787b6e93..84a9056c7 100644 --- a/electrum/gui/qml/qetypes.py +++ b/electrum/gui/qml/qetypes.py @@ -1,4 +1,4 @@ -from PyQt5.QtCore import pyqtProperty, pyqtSignal, pyqtSlot, QObject +from PyQt6.QtCore import pyqtProperty, pyqtSignal, pyqtSlot, QObject from electrum.logging import get_logger from electrum.i18n import _ diff --git a/electrum/gui/qml/qewallet.py b/electrum/gui/qml/qewallet.py index f21985384..12f714b7c 100644 --- a/electrum/gui/qml/qewallet.py +++ b/electrum/gui/qml/qewallet.py @@ -6,7 +6,7 @@ import time from typing import TYPE_CHECKING, Callable from functools import partial -from PyQt5.QtCore import pyqtProperty, pyqtSignal, pyqtSlot, QObject, QTimer +from PyQt6.QtCore import pyqtProperty, pyqtSignal, pyqtSlot, QObject, QTimer from electrum.i18n import _ from electrum.invoices import InvoiceError, PR_PAID, PR_BROADCASTING, PR_BROADCAST diff --git a/electrum/gui/qml/qewizard.py b/electrum/gui/qml/qewizard.py index e9aa95107..3bd12fb21 100644 --- a/electrum/gui/qml/qewizard.py +++ b/electrum/gui/qml/qewizard.py @@ -1,7 +1,7 @@ import os from typing import TYPE_CHECKING -from PyQt5.QtCore import pyqtProperty, pyqtSignal, pyqtSlot, QObject +from PyQt6.QtCore import pyqtProperty, pyqtSignal, pyqtSlot, QObject from electrum.logging import get_logger from electrum import mnemonic diff --git a/electrum/gui/qml/util.py b/electrum/gui/qml/util.py index 7d3442eeb..bebc62320 100644 --- a/electrum/gui/qml/util.py +++ b/electrum/gui/qml/util.py @@ -5,7 +5,7 @@ from functools import wraps from time import time from typing import Callable, Optional, NamedTuple -from PyQt5.QtCore import pyqtSignal, QThread +from PyQt6.QtCore import pyqtSignal, QThread from electrum.logging import Logger from electrum.util import EventListener, event_listener diff --git a/electrum/plugins/labels/qml.py b/electrum/plugins/labels/qml.py index ffd970fdb..b6045d8a0 100644 --- a/electrum/plugins/labels/qml.py +++ b/electrum/plugins/labels/qml.py @@ -1,6 +1,6 @@ import threading -from PyQt5.QtCore import pyqtSignal, pyqtSlot +from PyQt6.QtCore import pyqtSignal, pyqtSlot from electrum.i18n import _ from electrum.plugin import hook diff --git a/electrum/plugins/trustedcoin/common_qt.py b/electrum/plugins/trustedcoin/common_qt.py index 1638666ef..c960d5240 100644 --- a/electrum/plugins/trustedcoin/common_qt.py +++ b/electrum/plugins/trustedcoin/common_qt.py @@ -3,7 +3,7 @@ import socket import base64 from typing import TYPE_CHECKING -from PyQt5.QtCore import pyqtSignal, pyqtProperty, pyqtSlot +from PyQt6.QtCore import pyqtSignal, pyqtProperty, pyqtSlot # TODO: common code, Qt5/Qt6 mismatch! from electrum.i18n import _ from electrum.bip32 import BIP32Node diff --git a/electrum/plugins/trustedcoin/qml.py b/electrum/plugins/trustedcoin/qml.py index 56a03b401..00c44fc16 100644 --- a/electrum/plugins/trustedcoin/qml.py +++ b/electrum/plugins/trustedcoin/qml.py @@ -15,6 +15,7 @@ if TYPE_CHECKING: from electrum.wizard import NewWalletWizard + class Plugin(TrustedCoinPlugin): def __init__(self, *args):