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):
|
class ElectrumGui(Logger):
|
||||||
|
|
||||||
|
network_dialog: Optional['NetworkDialog']
|
||||||
|
lightning_dialog: Optional['LightningDialog']
|
||||||
|
watchtower_dialog: Optional['WatchtowerDialog']
|
||||||
|
|
||||||
@profiler
|
@profiler
|
||||||
def __init__(self, config: 'SimpleConfig', daemon: 'Daemon', plugins: 'Plugins'):
|
def __init__(self, config: 'SimpleConfig', daemon: 'Daemon', plugins: 'Plugins'):
|
||||||
set_language(config.get('language', get_default_language()))
|
set_language(config.get('language', get_default_language()))
|
||||||
@@ -111,6 +115,7 @@ class ElectrumGui(Logger):
|
|||||||
self.app = QElectrumApplication(sys.argv)
|
self.app = QElectrumApplication(sys.argv)
|
||||||
self.app.installEventFilter(self.efilter)
|
self.app.installEventFilter(self.efilter)
|
||||||
self.app.setWindowIcon(read_QIcon("electrum.png"))
|
self.app.setWindowIcon(read_QIcon("electrum.png"))
|
||||||
|
self._cleaned_up = False
|
||||||
# timer
|
# timer
|
||||||
self.timer = QTimer(self.app)
|
self.timer = QTimer(self.app)
|
||||||
self.timer.setSingleShot(False)
|
self.timer.setSingleShot(False)
|
||||||
@@ -199,15 +204,40 @@ class ElectrumGui(Logger):
|
|||||||
for w in self.windows:
|
for w in self.windows:
|
||||||
w.hide()
|
w.hide()
|
||||||
|
|
||||||
def close(self):
|
def _cleanup_before_exit(self):
|
||||||
for window in self.windows:
|
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.close()
|
||||||
|
window.clean_up()
|
||||||
if self.network_dialog:
|
if self.network_dialog:
|
||||||
self.network_dialog.close()
|
self.network_dialog.close()
|
||||||
|
self.network_dialog.clean_up()
|
||||||
|
self.network_dialog = None
|
||||||
|
self.network_updated_signal_obj = None
|
||||||
if self.lightning_dialog:
|
if self.lightning_dialog:
|
||||||
self.lightning_dialog.close()
|
self.lightning_dialog.close()
|
||||||
|
self.lightning_dialog = None
|
||||||
if self.watchtower_dialog:
|
if self.watchtower_dialog:
|
||||||
self.watchtower_dialog.close()
|
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()
|
self.app.quit()
|
||||||
|
|
||||||
def new_window(self, path, uri=None):
|
def new_window(self, path, uri=None):
|
||||||
@@ -232,8 +262,10 @@ class ElectrumGui(Logger):
|
|||||||
self.network_dialog.show()
|
self.network_dialog.show()
|
||||||
self.network_dialog.raise_()
|
self.network_dialog.raise_()
|
||||||
return
|
return
|
||||||
self.network_dialog = NetworkDialog(self.daemon.network, self.config,
|
self.network_dialog = NetworkDialog(
|
||||||
self.network_updated_signal_obj)
|
network=self.daemon.network,
|
||||||
|
config=self.config,
|
||||||
|
network_updated_signal_obj=self.network_updated_signal_obj)
|
||||||
self.network_dialog.show()
|
self.network_dialog.show()
|
||||||
|
|
||||||
def _create_window_for_wallet(self, wallet):
|
def _create_window_for_wallet(self, wallet):
|
||||||
@@ -382,18 +414,7 @@ class ElectrumGui(Logger):
|
|||||||
self.app.lastWindowClosed.connect(quit_after_last_window)
|
self.app.lastWindowClosed.connect(quit_after_last_window)
|
||||||
|
|
||||||
def clean_up():
|
def clean_up():
|
||||||
# If there are still some open windows, try to clean them up.
|
self._cleanup_before_exit()
|
||||||
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.app.aboutToQuit.connect(clean_up)
|
self.app.aboutToQuit.connect(clean_up)
|
||||||
|
|
||||||
# main loop
|
# main loop
|
||||||
|
|||||||
@@ -27,6 +27,7 @@ import socket
|
|||||||
import time
|
import time
|
||||||
from enum import IntEnum
|
from enum import IntEnum
|
||||||
from typing import Tuple, TYPE_CHECKING
|
from typing import Tuple, TYPE_CHECKING
|
||||||
|
import threading
|
||||||
|
|
||||||
from PyQt5.QtCore import Qt, pyqtSignal, QThread
|
from PyQt5.QtCore import Qt, pyqtSignal, QThread
|
||||||
from PyQt5.QtWidgets import (QTreeWidget, QTreeWidgetItem, QMenu, QGridLayout, QComboBox,
|
from PyQt5.QtWidgets import (QTreeWidget, QTreeWidgetItem, QMenu, QGridLayout, QComboBox,
|
||||||
@@ -53,7 +54,7 @@ protocol_names = ['TCP', 'SSL']
|
|||||||
protocol_letters = 'ts'
|
protocol_letters = 'ts'
|
||||||
|
|
||||||
class NetworkDialog(QDialog):
|
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)
|
QDialog.__init__(self)
|
||||||
self.setWindowTitle(_('Network'))
|
self.setWindowTitle(_('Network'))
|
||||||
self.setMinimumSize(500, 500)
|
self.setMinimumSize(500, 500)
|
||||||
@@ -68,19 +69,20 @@ class NetworkDialog(QDialog):
|
|||||||
self._cleaned_up = False
|
self._cleaned_up = False
|
||||||
|
|
||||||
def on_network(self, event, *args):
|
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):
|
def on_update(self):
|
||||||
self.nlayout.update()
|
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):
|
def clean_up(self):
|
||||||
|
if self._cleaned_up:
|
||||||
|
return
|
||||||
|
self._cleaned_up = True
|
||||||
self.nlayout.clean_up()
|
self.nlayout.clean_up()
|
||||||
|
self.network_updated_signal_obj.network_updated_signal.disconnect()
|
||||||
|
self.network_updated_signal_obj = None
|
||||||
|
|
||||||
|
|
||||||
class NodesListWidget(QTreeWidget):
|
class NodesListWidget(QTreeWidget):
|
||||||
@@ -320,8 +322,7 @@ class NetworkChoiceLayout(object):
|
|||||||
def clean_up(self):
|
def clean_up(self):
|
||||||
if self.td:
|
if self.td:
|
||||||
self.td.found_proxy.disconnect()
|
self.td.found_proxy.disconnect()
|
||||||
self.td.exit()
|
self.td.stop()
|
||||||
self.td.wait()
|
|
||||||
self.td = None
|
self.td = None
|
||||||
|
|
||||||
def check_disable_proxy(self, b):
|
def check_disable_proxy(self, b):
|
||||||
@@ -463,6 +464,7 @@ class TorDetector(QThread):
|
|||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
QThread.__init__(self)
|
QThread.__init__(self)
|
||||||
|
self._stop_event = threading.Event()
|
||||||
|
|
||||||
def run(self):
|
def run(self):
|
||||||
# Probable ports for Tor to listen at
|
# Probable ports for Tor to listen at
|
||||||
@@ -475,7 +477,14 @@ class TorDetector(QThread):
|
|||||||
break
|
break
|
||||||
else:
|
else:
|
||||||
self.found_proxy.emit(None)
|
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
|
@staticmethod
|
||||||
def is_tor_port(net_addr: Tuple[str, int]) -> bool:
|
def is_tor_port(net_addr: Tuple[str, int]) -> bool:
|
||||||
|
|||||||
Reference in New Issue
Block a user