qt: even more clean-up before exiting
related: https://github.com/spesmilo/electrum/issues/6889#issuecomment-812776695
This commit is contained in:
@@ -88,6 +88,10 @@ class QNetworkUpdatedSignalObject(QObject):
|
||||
|
||||
class ElectrumGui(Logger):
|
||||
|
||||
network_dialog: Optional['NetworkDialog']
|
||||
lightning_dialog: Optional['LightningDialog']
|
||||
watchtower_dialog: Optional['WatchtowerDialog']
|
||||
|
||||
@profiler
|
||||
def __init__(self, config: 'SimpleConfig', daemon: 'Daemon', plugins: 'Plugins'):
|
||||
set_language(config.get('language', get_default_language()))
|
||||
@@ -111,6 +115,7 @@ class ElectrumGui(Logger):
|
||||
self.app = QElectrumApplication(sys.argv)
|
||||
self.app.installEventFilter(self.efilter)
|
||||
self.app.setWindowIcon(read_QIcon("electrum.png"))
|
||||
self._cleaned_up = False
|
||||
# timer
|
||||
self.timer = QTimer(self.app)
|
||||
self.timer.setSingleShot(False)
|
||||
@@ -199,15 +204,40 @@ class ElectrumGui(Logger):
|
||||
for w in self.windows:
|
||||
w.hide()
|
||||
|
||||
def close(self):
|
||||
for window in self.windows:
|
||||
def _cleanup_before_exit(self):
|
||||
if self._cleaned_up:
|
||||
return
|
||||
self._cleaned_up = True
|
||||
self.app.new_window_signal.disconnect()
|
||||
self.efilter = None
|
||||
# If there are still some open windows, try to clean them up.
|
||||
for window in list(self.windows):
|
||||
window.close()
|
||||
window.clean_up()
|
||||
if self.network_dialog:
|
||||
self.network_dialog.close()
|
||||
self.network_dialog.clean_up()
|
||||
self.network_dialog = None
|
||||
self.network_updated_signal_obj = None
|
||||
if self.lightning_dialog:
|
||||
self.lightning_dialog.close()
|
||||
self.lightning_dialog = None
|
||||
if self.watchtower_dialog:
|
||||
self.watchtower_dialog.close()
|
||||
self.watchtower_dialog = None
|
||||
# Shut down the timer cleanly
|
||||
self.timer.stop()
|
||||
self.timer = None
|
||||
# clipboard persistence. see http://www.mail-archive.com/pyqt@riverbankcomputing.com/msg17328.html
|
||||
event = QtCore.QEvent(QtCore.QEvent.Clipboard)
|
||||
self.app.sendEvent(self.app.clipboard(), event)
|
||||
if self.tray:
|
||||
self.tray.hide()
|
||||
self.tray.deleteLater()
|
||||
self.tray = None
|
||||
|
||||
def close(self):
|
||||
self._cleanup_before_exit()
|
||||
self.app.quit()
|
||||
|
||||
def new_window(self, path, uri=None):
|
||||
@@ -232,8 +262,10 @@ class ElectrumGui(Logger):
|
||||
self.network_dialog.show()
|
||||
self.network_dialog.raise_()
|
||||
return
|
||||
self.network_dialog = NetworkDialog(self.daemon.network, self.config,
|
||||
self.network_updated_signal_obj)
|
||||
self.network_dialog = NetworkDialog(
|
||||
network=self.daemon.network,
|
||||
config=self.config,
|
||||
network_updated_signal_obj=self.network_updated_signal_obj)
|
||||
self.network_dialog.show()
|
||||
|
||||
def _create_window_for_wallet(self, wallet):
|
||||
@@ -382,18 +414,7 @@ class ElectrumGui(Logger):
|
||||
self.app.lastWindowClosed.connect(quit_after_last_window)
|
||||
|
||||
def clean_up():
|
||||
# If there are still some open windows, try to clean them up.
|
||||
for window in list(self.windows):
|
||||
window.clean_up()
|
||||
# Shut down the timer cleanly
|
||||
self.timer.stop()
|
||||
# clipboard persistence. see http://www.mail-archive.com/pyqt@riverbankcomputing.com/msg17328.html
|
||||
event = QtCore.QEvent(QtCore.QEvent.Clipboard)
|
||||
self.app.sendEvent(self.app.clipboard(), event)
|
||||
if self.tray:
|
||||
self.tray.hide()
|
||||
self.tray.deleteLater()
|
||||
self.tray = None
|
||||
self._cleanup_before_exit()
|
||||
self.app.aboutToQuit.connect(clean_up)
|
||||
|
||||
# main loop
|
||||
|
||||
@@ -27,6 +27,7 @@ import socket
|
||||
import time
|
||||
from enum import IntEnum
|
||||
from typing import Tuple, TYPE_CHECKING
|
||||
import threading
|
||||
|
||||
from PyQt5.QtCore import Qt, pyqtSignal, QThread
|
||||
from PyQt5.QtWidgets import (QTreeWidget, QTreeWidgetItem, QMenu, QGridLayout, QComboBox,
|
||||
@@ -53,7 +54,7 @@ protocol_names = ['TCP', 'SSL']
|
||||
protocol_letters = 'ts'
|
||||
|
||||
class NetworkDialog(QDialog):
|
||||
def __init__(self, network, config, network_updated_signal_obj):
|
||||
def __init__(self, *, network: Network, config: 'SimpleConfig', network_updated_signal_obj):
|
||||
QDialog.__init__(self)
|
||||
self.setWindowTitle(_('Network'))
|
||||
self.setMinimumSize(500, 500)
|
||||
@@ -68,19 +69,20 @@ class NetworkDialog(QDialog):
|
||||
self._cleaned_up = False
|
||||
|
||||
def on_network(self, event, *args):
|
||||
self.network_updated_signal_obj.network_updated_signal.emit(event, args)
|
||||
signal_obj = self.network_updated_signal_obj
|
||||
if signal_obj:
|
||||
signal_obj.network_updated_signal.emit(event, args)
|
||||
|
||||
def on_update(self):
|
||||
self.nlayout.update()
|
||||
|
||||
def closeEvent(self, event):
|
||||
if not self._cleaned_up:
|
||||
self._cleaned_up = True
|
||||
self.clean_up()
|
||||
event.accept()
|
||||
|
||||
def clean_up(self):
|
||||
if self._cleaned_up:
|
||||
return
|
||||
self._cleaned_up = True
|
||||
self.nlayout.clean_up()
|
||||
self.network_updated_signal_obj.network_updated_signal.disconnect()
|
||||
self.network_updated_signal_obj = None
|
||||
|
||||
|
||||
class NodesListWidget(QTreeWidget):
|
||||
@@ -320,8 +322,7 @@ class NetworkChoiceLayout(object):
|
||||
def clean_up(self):
|
||||
if self.td:
|
||||
self.td.found_proxy.disconnect()
|
||||
self.td.exit()
|
||||
self.td.wait()
|
||||
self.td.stop()
|
||||
self.td = None
|
||||
|
||||
def check_disable_proxy(self, b):
|
||||
@@ -463,6 +464,7 @@ class TorDetector(QThread):
|
||||
|
||||
def __init__(self):
|
||||
QThread.__init__(self)
|
||||
self._stop_event = threading.Event()
|
||||
|
||||
def run(self):
|
||||
# Probable ports for Tor to listen at
|
||||
@@ -475,7 +477,14 @@ class TorDetector(QThread):
|
||||
break
|
||||
else:
|
||||
self.found_proxy.emit(None)
|
||||
time.sleep(10)
|
||||
stopping = self._stop_event.wait(10)
|
||||
if stopping:
|
||||
return
|
||||
|
||||
def stop(self):
|
||||
self._stop_event.set()
|
||||
self.exit()
|
||||
self.wait()
|
||||
|
||||
@staticmethod
|
||||
def is_tor_port(net_addr: Tuple[str, int]) -> bool:
|
||||
|
||||
Reference in New Issue
Block a user