From 1088cf444497b2548ba69aaaf755da6b83a477a8 Mon Sep 17 00:00:00 2001 From: SomberNight Date: Tue, 10 Dec 2019 03:34:41 +0100 Subject: [PATCH] qt: introduce BlockingWaitingDialog A variant of WaitingDialog that runs the task in the GUI thread, blocking the GUI. It is probably a code smell to actually use this, as operations should not block the GUI... still it provides a middle-ground between blocking the GUI without giving user-feedback and having to refactor existing code (to avoid blocking). --- electrum/gui/qt/confirm_tx_dialog.py | 4 ++-- electrum/gui/qt/util.py | 24 ++++++++++++++++++++++-- 2 files changed, 24 insertions(+), 4 deletions(-) diff --git a/electrum/gui/qt/confirm_tx_dialog.py b/electrum/gui/qt/confirm_tx_dialog.py index dbac7164f..3d274d9c8 100644 --- a/electrum/gui/qt/confirm_tx_dialog.py +++ b/electrum/gui/qt/confirm_tx_dialog.py @@ -34,7 +34,7 @@ from electrum.transaction import Transaction, PartialTransaction from electrum.simple_config import FEERATE_WARNING_HIGH_FEE from electrum.wallet import InternalAddressCorruption -from .util import WindowModalDialog, ColorScheme, HelpLabel, Buttons, CancelButton +from .util import WindowModalDialog, ColorScheme, HelpLabel, Buttons, CancelButton, BlockingWaitingDialog from .fee_slider import FeeSlider @@ -156,7 +156,7 @@ class ConfirmTxDialog(TxEditor, WindowModalDialog): self.send_button.clicked.connect(self.on_send) self.send_button.setDefault(True) vbox.addLayout(Buttons(CancelButton(self), self.send_button)) - self.update_tx() + BlockingWaitingDialog(window, _("Preparing transaction..."), self.update_tx) self.update() self.is_send = False diff --git a/electrum/gui/qt/util.py b/electrum/gui/qt/util.py index 195769a2c..449b41032 100644 --- a/electrum/gui/qt/util.py +++ b/electrum/gui/qt/util.py @@ -9,7 +9,7 @@ import os import webbrowser from functools import partial, lru_cache -from typing import NamedTuple, Callable, Optional, TYPE_CHECKING, Union, List, Dict +from typing import NamedTuple, Callable, Optional, TYPE_CHECKING, Union, List, Dict, Any from PyQt5.QtGui import (QFont, QColor, QCursor, QPixmap, QStandardItem, QPalette, QIcon, QFontMetrics) @@ -280,7 +280,7 @@ class WindowModalDialog(QDialog, MessageBoxMixin): class WaitingDialog(WindowModalDialog): '''Shows a please wait dialog whilst running a task. It is not necessary to maintain a reference to this dialog.''' - def __init__(self, parent, message, task, on_success=None, on_error=None): + def __init__(self, parent: QWidget, message: str, task, on_success=None, on_error=None): assert parent if isinstance(parent, MessageBoxMixin): parent = parent.top_level_window() @@ -305,6 +305,26 @@ class WaitingDialog(WindowModalDialog): self.message_label.setText(msg) +class BlockingWaitingDialog(WindowModalDialog): + """Shows a waiting dialog whilst running a task. + Should be called from the GUI thread. The GUI thread will be blocked while + the task is running; the point of the dialog is to provide feedback + to the user regarding what is going on. + """ + def __init__(self, parent: QWidget, message: str, task: Callable[[], Any]): + assert parent + if isinstance(parent, MessageBoxMixin): + parent = parent.top_level_window() + WindowModalDialog.__init__(self, parent, _("Please wait")) + self.message_label = QLabel(message) + vbox = QVBoxLayout(self) + vbox.addWidget(self.message_label) + self.show() + QCoreApplication.processEvents() + task() + self.accept() + + def line_dialog(parent, title, label, ok_label, default=None): dialog = WindowModalDialog(parent, title) dialog.setMinimumWidth(500)