gui: Fix crash when quickly opening/closing applets

Quickly closing/reopening applets (e.g. quickly clicking the checkbox
on an entire folder of applets) would previously lead to an occasional
KeyError on the self.dock_to_item access in on_dock_closed, as close()
would be invoked more than once.

The geometry/checked state handling can potentially be cleaned up
further, but at least this avoid the crash.
This commit is contained in:
David Nadlinger 2019-03-10 20:44:14 +00:00
parent e47ba4b35e
commit 5fd92a6175
1 changed files with 6 additions and 10 deletions

View File

@ -321,7 +321,6 @@ class AppletsDock(QtWidgets.QDockWidget):
self.main_window = main_window self.main_window = main_window
self.datasets_sub = datasets_sub self.datasets_sub = datasets_sub
self.dock_to_item = dict()
self.applet_uids = set() self.applet_uids = set()
self.table = QtWidgets.QTreeWidget() self.table = QtWidgets.QTreeWidget()
@ -414,12 +413,12 @@ class AppletsDock(QtWidgets.QDockWidget):
finally: finally:
self.table.itemChanged.connect(self.item_changed) self.table.itemChanged.connect(self.item_changed)
def create(self, uid, name, spec): def create(self, item, name, spec):
dock = _AppletDock(self.datasets_sub, uid, name, spec) dock = _AppletDock(self.datasets_sub, item.applet_uid, name, spec)
self.main_window.addDockWidget(QtCore.Qt.RightDockWidgetArea, dock) self.main_window.addDockWidget(QtCore.Qt.RightDockWidgetArea, dock)
dock.setFloating(True) dock.setFloating(True)
asyncio.ensure_future(dock.start()) asyncio.ensure_future(dock.start())
dock.sigClosed.connect(partial(self.on_dock_closed, dock)) dock.sigClosed.connect(partial(self.on_dock_closed, item, dock))
return dock return dock
def item_changed(self, item, column): def item_changed(self, item, column):
@ -437,15 +436,15 @@ class AppletsDock(QtWidgets.QDockWidget):
if item.applet_dock is None: if item.applet_dock is None:
name = item.text(0) name = item.text(0)
spec = self.get_spec(item) spec = self.get_spec(item)
dock = self.create(item.applet_uid, name, spec) dock = self.create(item, name, spec)
item.applet_dock = dock item.applet_dock = dock
if item.applet_geometry is not None: if item.applet_geometry is not None:
dock.restoreGeometry(item.applet_geometry) dock.restoreGeometry(item.applet_geometry)
# geometry is now handled by main window state # geometry is now handled by main window state
item.applet_geometry = None item.applet_geometry = None
self.dock_to_item[dock] = item
else: else:
dock = item.applet_dock dock = item.applet_dock
item.applet_dock = None
if dock is not None: if dock is not None:
# This calls self.on_dock_closed # This calls self.on_dock_closed
dock.close() dock.close()
@ -455,12 +454,9 @@ class AppletsDock(QtWidgets.QDockWidget):
else: else:
raise ValueError raise ValueError
def on_dock_closed(self, dock): def on_dock_closed(self, item, dock):
item = self.dock_to_item[dock]
item.applet_dock = None
item.applet_geometry = dock.saveGeometry() item.applet_geometry = dock.saveGeometry()
asyncio.ensure_future(dock.terminate()) asyncio.ensure_future(dock.terminate())
del self.dock_to_item[dock]
item.setCheckState(0, QtCore.Qt.Unchecked) item.setCheckState(0, QtCore.Qt.Unchecked)
def get_untitled(self): def get_untitled(self):