common_qt: move QtEventListener and qt_event_listener decorator to common_qt

This commit is contained in:
Sander van Grieken
2026-03-03 12:59:49 +01:00
parent 161142ddb0
commit 91efb3e1f4
24 changed files with 92 additions and 97 deletions
+32
View File
@@ -1,5 +1,6 @@
import queue
import sys
from functools import wraps
from typing import Optional, NamedTuple, Callable
import os.path
@@ -10,6 +11,7 @@ import qrcode
from electrum.i18n import _
from electrum.logging import Logger
from electrum.util import EventListener, event_listener
_cached_font_ids: dict[str, int] = {}
@@ -190,3 +192,33 @@ class TaskThread(QThread, Logger):
self.tasks.put(None) # in case the thread is still waiting on the queue
self.exit()
self.wait()
class QtEventListener(EventListener):
qt_callback_signal = pyqtSignal(tuple)
def register_callbacks(self):
self.qt_callback_signal.connect(self.on_qt_callback_signal)
EventListener.register_callbacks(self)
def unregister_callbacks(self):
try:
self.qt_callback_signal.disconnect()
except (RuntimeError, TypeError): # wrapped Qt object might be deleted
# "TypeError: disconnect() failed between 'qt_callback_signal' and all its connections"
pass
EventListener.unregister_callbacks(self)
def on_qt_callback_signal(self, args):
func = args[0]
return func(self, *args[1:])
# decorator for members of the QtEventListener class
def qt_event_listener(func):
func = event_listener(func)
@wraps(func)
def decorator(self, *args):
self.qt_callback_signal.emit((func,) + args)
return decorator
+4 -2
View File
@@ -5,10 +5,12 @@ from PyQt6.QtCore import Qt, QAbstractListModel, QModelIndex
from electrum.logging import get_logger
from electrum.util import Satoshis
from .qeconfig import QEConfig
from electrum.gui.common_qt.util import QtEventListener, qt_event_listener
from .qeconfig import QEConfig
from .qetypes import QEAmount
from .util import qt_event_listener, QtEventListener
if TYPE_CHECKING:
from electrum.wallet import Abstract_Wallet
+3 -2
View File
@@ -9,12 +9,13 @@ from electrum.gui import messages
from electrum.logging import get_logger
from electrum.lnutil import LOCAL, REMOTE
from electrum.lnchannel import ChanCloseOption, ChannelState, AbstractChannel, Channel, ChannelBackup
from electrum.util import format_short_id
from electrum.util import format_short_id, event_listener
from electrum.gui.common_qt.util import QtEventListener
from .auth import AuthMixin, auth_protect
from .qewallet import QEWallet
from .qetypes import QEAmount
from .util import QtEventListener, event_listener
if TYPE_CHECKING:
from electrum.wallet import Abstract_Wallet
+2 -1
View File
@@ -7,8 +7,9 @@ from electrum.logging import get_logger
from electrum.util import Satoshis
from electrum.gui import messages
from electrum.gui.common_qt.util import qt_event_listener, QtEventListener
from .qetypes import QEAmount
from .util import QtEventListener, qt_event_listener
from .qemodelfilter import QEFilterProxyModel
+3 -1
View File
@@ -7,9 +7,11 @@ from electrum.bitcoin import COIN
from electrum.exchange_rate import FxThread
from electrum.logging import get_logger
from electrum.simple_config import SimpleConfig
from electrum.util import event_listener
from electrum.gui.common_qt.util import QtEventListener
from .qetypes import QEAmount
from .util import QtEventListener, event_listener
class QEFX(QObject, QtEventListener):
+4 -1
View File
@@ -19,10 +19,13 @@ from electrum.bitcoin import COIN, address_to_script
from electrum.paymentrequest import PaymentRequest
from electrum.payment_identifier import PaymentIdentifier, PaymentIdentifierState, PaymentIdentifierType
from electrum.network import Network
from electrum.util import event_listener
from electrum.gui.common_qt.util import QtEventListener
from .qetypes import QEAmount
from .qewallet import QEWallet
from .util import status_update_timer_interval, QtEventListener, event_listener
from .util import status_update_timer_interval
from ...util import InvoiceError
+3 -1
View File
@@ -8,7 +8,9 @@ from electrum.logging import get_logger
from electrum.util import Satoshis, format_time
from electrum.invoices import BaseInvoice, PR_EXPIRED, LN_EXPIRY_NEVER, Invoice, Request, PR_PAID
from .util import QtEventListener, qt_event_listener, status_update_timer_interval
from electrum.gui.common_qt.util import QtEventListener, qt_event_listener
from .util import status_update_timer_interval
from .qetypes import QEAmount
if TYPE_CHECKING:
+3 -1
View File
@@ -7,8 +7,10 @@ from electrum import constants
from electrum.network import ProxySettings
from electrum.interface import ServerAddr
from electrum.fee_policy import FEERATE_DEFAULT_RELAY
from electrum.util import event_listener
from electrum.gui.common_qt.util import QtEventListener
from .util import QtEventListener, event_listener
from .qeconfig import QEConfig
from .qeserverlistmodel import QEServerListModel
+3 -1
View File
@@ -14,9 +14,11 @@ from electrum.payment_identifier import PaymentIdentifier, PaymentIdentifierType
from electrum.i18n import _
from electrum.network import Network
from electrum.gui.common_qt.util import QtEventListener, qt_event_listener
from .qewallet import QEWallet
from .qetypes import QEAmount
from .util import QtEventListener, qt_event_listener, status_update_timer_interval
from .util import status_update_timer_interval
class QERequestDetails(QObject, QtEventListener):
+1 -1
View File
@@ -6,7 +6,7 @@ from electrum.util import Satoshis
from electrum.interface import ServerAddr, PREFERRED_NETWORK_PROTOCOL
from electrum import blockchain
from .util import QtEventListener, qt_event_listener
from electrum.gui.common_qt.util import QtEventListener, qt_event_listener
class QEServerListModel(QAbstractListModel, QtEventListener):
+2 -1
View File
@@ -18,10 +18,11 @@ from electrum.fee_policy import FeePolicy
from electrum.gui import messages
from electrum.gui.common_qt.util import QtEventListener, qt_event_listener
from .auth import AuthMixin, auth_protect
from .qetypes import QEAmount
from .qewallet import QEWallet
from .util import QtEventListener, qt_event_listener
if TYPE_CHECKING:
import concurrent.futures
+2 -1
View File
@@ -8,8 +8,9 @@ from electrum.logging import get_logger
from electrum.util import Satoshis, TxMinedInfo
from electrum.address_synchronizer import TX_HEIGHT_FUTURE, TX_HEIGHT_LOCAL
from electrum.gui.common_qt.util import QtEventListener, qt_event_listener
from .qetypes import QEAmount
from .util import QtEventListener, qt_event_listener
if TYPE_CHECKING:
from electrum.wallet import Abstract_Wallet
+2 -1
View File
@@ -12,9 +12,10 @@ from electrum.address_synchronizer import TX_HEIGHT_UNCONF_PARENT, TX_HEIGHT_UNC
from electrum.wallet import TxSighashDanger
from electrum.fee_policy import FeePolicy
from electrum.gui.common_qt.util import QtEventListener, qt_event_listener
from .qewallet import QEWallet
from .qetypes import QEAmount
from .util import QtEventListener, qt_event_listener
class QETxDetails(QObject, QtEventListener):
+4 -2
View File
@@ -11,7 +11,9 @@ from electrum.logging import get_logger
from electrum.i18n import _
from electrum.bitcoin import DummyAddress
from electrum.transaction import PartialTxOutput, PartialTransaction, Transaction, TxOutpoint
from electrum.util import NotEnoughFunds, profiler, quantize_feerate, UserFacingException, NoDynamicFeeEstimates
from electrum.util import (
NotEnoughFunds, profiler, quantize_feerate, UserFacingException, NoDynamicFeeEstimates, event_listener
)
from electrum.wallet import CannotBumpFee, CannotDoubleSpendTx, CannotCPFP, BumpFeeStrategy, sweep_preparations
from electrum import keystore
from electrum.plugin import run_hook
@@ -19,10 +21,10 @@ from electrum.fee_policy import FeePolicy, FeeMethod
from electrum.network import NetworkException
from electrum.gui import messages
from electrum.gui.common_qt.util import QtEventListener
from .qewallet import QEWallet
from .qetypes import QEAmount
from .util import QtEventListener, event_listener
if TYPE_CHECKING:
from electrum.simple_config import SimpleConfig
+5 -3
View File
@@ -13,21 +13,23 @@ from electrum.invoices import InvoiceError, PR_PAID, PR_BROADCASTING, PR_BROADCA
from electrum.logging import get_logger
from electrum.network import TxBroadcastError, BestEffortRequestFailed
from electrum.transaction import PartialTransaction, Transaction
from electrum.util import InvalidPassword, event_listener, AddTransactionException, get_asyncio_loop, NotEnoughFunds, \
NoDynamicFeeEstimates
from electrum.util import (
InvalidPassword, event_listener, AddTransactionException, get_asyncio_loop, NotEnoughFunds, NoDynamicFeeEstimates
)
from electrum.lnutil import MIN_FUNDING_SAT
from electrum.plugin import run_hook
from electrum.wallet import Multisig_Wallet
from electrum.crypto import pw_decode_with_version_and_mac
from electrum.fee_policy import FeePolicy, FixedFeePolicy
from electrum.gui.common_qt.util import QtEventListener, qt_event_listener
from .auth import AuthMixin, auth_protect
from .qeaddresslistmodel import QEAddressCoinListModel
from .qechannellistmodel import QEChannelListModel
from .qeinvoicelistmodel import QEInvoiceListModel, QERequestListModel
from .qetransactionlistmodel import QETransactionListModel
from .qetypes import QEAmount
from .util import QtEventListener, qt_event_listener
if TYPE_CHECKING:
from electrum.wallet import Abstract_Wallet
-30
View File
@@ -1,40 +1,10 @@
import math
import re
from functools import wraps
from time import time
from typing import Tuple
from PyQt6.QtCore import pyqtSignal
from electrum.i18n import _
from electrum.util import EventListener, event_listener
class QtEventListener(EventListener):
qt_callback_signal = pyqtSignal(tuple)
def register_callbacks(self):
self.qt_callback_signal.connect(self.on_qt_callback_signal)
EventListener.register_callbacks(self)
def unregister_callbacks(self):
#self.qt_callback_signal.disconnect()
EventListener.unregister_callbacks(self)
def on_qt_callback_signal(self, args):
func = args[0]
return func(self, *args[1:])
# decorator for members of the QtEventListener class
def qt_event_listener(func):
func = event_listener(func)
@wraps(func)
def decorator(self, *args):
self.qt_callback_signal.emit( (func,) + args)
return decorator
# return delay in msec when expiry time string should be updated
+2 -2
View File
@@ -14,8 +14,8 @@ from electrum.lnaddr import LnAddr, lndecode
from electrum.bitcoin import COIN
from electrum.wallet import Abstract_Wallet
from .util import Buttons, CloseButton, ShowQRLineEdit, MessageBoxMixin, WWLabel
from .util import QtEventListener, qt_event_listener, VLine
from electrum.gui.common_qt.util import QtEventListener, qt_event_listener
from .util import Buttons, CloseButton, ShowQRLineEdit, MessageBoxMixin, WWLabel, VLine
if TYPE_CHECKING:
from .main_window import ElectrumWindow
+3 -2
View File
@@ -47,9 +47,10 @@ from electrum.logging import Logger
from electrum.submarine_swaps import NostrTransport, HttpTransport, SwapServerTransport, SwapServerError
from electrum.gui.messages import MSG_SUBMARINE_PAYMENT_HELP_TEXT
from electrum.gui.common_qt.util import QtEventListener, qt_event_listener
from .util import (WindowModalDialog, ColorScheme, HelpLabel, Buttons, CancelButton, WWLabel,
read_QIcon, qt_event_listener, QtEventListener, IconLabel,
HelpButton, RunCoroutineDialog)
read_QIcon, IconLabel, HelpButton, RunCoroutineDialog)
from .transaction_dialog import TxSizeLabel, TxFiatLabel, TxInOutWidget
from .fee_slider import FeeSlider, FeeComboBox
from .amountedit import FeerateEdit, BTCAmountEdit
+2 -1
View File
@@ -29,8 +29,9 @@ from PyQt6.QtWidgets import (QDialog, QLabel, QVBoxLayout, QPushButton)
from electrum.i18n import _
from electrum.gui.common_qt.util import QtEventListener, qt_event_listener
from .util import Buttons
from .util import QtEventListener, qt_event_listener
if TYPE_CHECKING:
from . import ElectrumGui
+4 -5
View File
@@ -58,7 +58,7 @@ from electrum.util import (format_time, UserCancelled, profiler, bfh, InvalidPas
UserFacingException, get_new_wallet_name,
send_exception_to_crash_reporter,
AddTransactionException, os_chmod, UI_UNIT_NAME_TXSIZE_VBYTES,
is_valid_email, ChoiceItem)
is_valid_email, ChoiceItem, event_listener)
from electrum.bip21 import BITCOIN_BIP21_URI_SCHEME
from electrum.payment_identifier import PaymentIdentifier
from electrum.invoices import PR_PAID, Invoice
@@ -77,6 +77,8 @@ from electrum.lnaddr import lndecode, LnAddr
from electrum.submarine_swaps import SwapServerTransport, NostrTransport
from electrum.fee_policy import FeePolicy
from electrum.gui.common_qt.util import TaskThread, QtEventListener, qt_event_listener
from .rate_limiter import rate_limited
from .exception_window import Exception_Hook
from .amountedit import BTCAmountEdit
@@ -90,8 +92,7 @@ from .util import (read_QIcon, ColorScheme, text_dialog, icon_path, WaitingDialo
CloseButton, MessageBoxMixin, EnterButton, import_meta_gui, export_meta_gui,
filename_field, address_field, char_width_in_lineedit, webopen,
TRANSACTION_FILE_EXTENSION_FILTER_ANY, MONOSPACE_FONT,
getOpenFileName, getSaveFileName, ShowQRLineEdit, QtEventListener, qt_event_listener,
event_listener, scan_qr_from_screenshot)
getOpenFileName, getSaveFileName, ShowQRLineEdit, scan_qr_from_screenshot)
from .wizard.wallet import WIF_HELP_TEXT
from .history_list import HistoryList, HistoryModel
from .update_checker import UpdateCheck, UpdateCheckThread
@@ -103,8 +104,6 @@ from .swap_dialog import SwapDialog, InvalidSwapParameters
from .balance_dialog import (BalanceToolButton, COLOR_FROZEN, COLOR_UNMATURED, COLOR_UNCONFIRMED, COLOR_CONFIRMED,
COLOR_LIGHTNING, COLOR_FROZEN_LIGHTNING)
from electrum.gui.common_qt.util import TaskThread
if TYPE_CHECKING:
from . import ElectrumGui
from electrum.submarine_swaps import SwapOffer
+2 -3
View File
@@ -41,12 +41,11 @@ from electrum.logging import get_logger
from electrum.util import is_valid_websocket_url
from electrum.gui import messages
from electrum.gui.common_qt.util import QtEventListener, qt_event_listener
from .util import (
Buttons, CloseButton, HelpButton, read_QIcon, char_width_in_lineedit, PasswordLineEdit, QtEventListener,
qt_event_listener, Spinner, HelpLabel
Buttons, CloseButton, HelpButton, read_QIcon, char_width_in_lineedit, PasswordLineEdit, Spinner, HelpLabel
)
_logger = get_logger(__name__)
protocol_names = ['TCP', 'SSL']
+2 -2
View File
@@ -35,10 +35,10 @@ from electrum.i18n import _, get_gui_lang_names
from electrum import util
from electrum.util import base_units_list, event_listener
from electrum.gui.common_qt.util import QtEventListener
from electrum.gui import messages
from .util import ColorScheme, HelpLabel, Buttons, CloseButton, QtEventListener
from .util import ColorScheme, HelpLabel, Buttons, CloseButton
if TYPE_CHECKING:
from electrum.simple_config import SimpleConfig, ConfigVarWithConfig
+2 -1
View File
@@ -15,12 +15,13 @@ from electrum.transaction import PartialTxOutput, PartialTransaction
from electrum.fee_policy import FeePolicy
from electrum.submarine_swaps import NostrTransport
from electrum.gui.common_qt.util import QtEventListener, qt_event_listener
from electrum.gui import messages
from . import util
from .util import (WindowModalDialog, Buttons, OkButton, CancelButton,
EnterButton, ColorScheme, WWLabel, read_QIcon, IconLabel, char_width_in_lineedit,
pubkey_to_q_icon)
from .util import qt_event_listener, QtEventListener
from .amountedit import BTCAmountEdit
from .fee_slider import FeeSlider, FeeComboBox
from .my_treeview import create_toolbar_with_menu, MyTreeView
+2 -32
View File
@@ -7,7 +7,7 @@ import queue
import os
import webbrowser
import ctypes
from functools import partial, lru_cache, wraps
from functools import partial, lru_cache
from typing import (NamedTuple, Callable, Optional, TYPE_CHECKING, List, Any, Sequence, Tuple, Union)
from PyQt6 import QtCore
@@ -21,7 +21,7 @@ from PyQt6.QtWidgets import (QPushButton, QLabel, QMessageBox, QHBoxLayout, QVBo
QFrame, QAbstractButton)
from electrum.i18n import _
from electrum.util import (FileImportFailed, FileExportFailed, resource_path, EventListener, event_listener,
from electrum.util import (FileImportFailed, FileExportFailed, resource_path, EventListener,
get_logger, UserCancelled, UserFacingException, ChoiceItem)
from electrum.invoices import (PR_UNPAID, PR_PAID, PR_EXPIRED, PR_INFLIGHT, PR_UNKNOWN, PR_FAILED, PR_ROUTING,
PR_UNCONFIRMED, PR_BROADCASTING, PR_BROADCAST)
@@ -1480,36 +1480,6 @@ class ImageGraphicsEffect(QObject):
return result
class QtEventListener(EventListener):
qt_callback_signal = QtCore.pyqtSignal(tuple)
def register_callbacks(self):
self.qt_callback_signal.connect(self.on_qt_callback_signal)
EventListener.register_callbacks(self)
def unregister_callbacks(self):
try:
self.qt_callback_signal.disconnect()
except (RuntimeError, TypeError): # wrapped Qt object might be deleted
# "TypeError: disconnect() failed between 'qt_callback_signal' and all its connections"
pass
EventListener.unregister_callbacks(self)
def on_qt_callback_signal(self, args):
func = args[0]
return func(self, *args[1:])
# decorator for members of the QtEventListener class
def qt_event_listener(func):
func = event_listener(func)
@wraps(func)
def decorator(self, *args):
self.qt_callback_signal.emit( (func,) + args)
return decorator
def insert_spaces(text: str, every_chars: int) -> str:
'''Insert spaces at every Nth character to allow for WordWrap'''
return ' '.join(text[i:i+every_chars] for i in range(0, len(text), every_chars))