diff --git a/test/test_mainwindow.py b/test/test_mainwindow.py index b16d85d..d43771d 100644 --- a/test/test_mainwindow.py +++ b/test/test_mainwindow.py @@ -114,3 +114,14 @@ def check_file_format(filename: str) -> None: check_file_format("demo.zxg") check_file_format("demo.zxp") check_file_format("demo.zxr") + + +def test_proof_cleanup_before_close(app: MainWindow, qtbot: QtBot) -> None: + # Regression test to check that the app doesn't crash when closing a proof tab with a derivation in progress, + # due to accessing the graph after it has been deallocated. + # See https://github.com/Quantomatic/zxlive/issues/218 for context. + assert app.active_panel is not None + assert isinstance(app.active_panel, GraphEditPanel) + qtbot.mouseClick(app.active_panel.start_derivation, QtCore.Qt.MouseButton.LeftButton) + app.select_all_action.trigger() + app.close_action.trigger() diff --git a/zxlive/mainwindow.py b/zxlive/mainwindow.py index 006783c..7e06b5c 100644 --- a/zxlive/mainwindow.py +++ b/zxlive/mainwindow.py @@ -308,7 +308,8 @@ def close_tab(self, i: int) -> bool: if i == -1: return False widget = self.tab_widget.widget(i) - if isinstance(widget, BasePanel) and not widget.undo_stack.isClean(): + assert isinstance(widget, BasePanel) + if not widget.undo_stack.isClean(): name = self.tab_widget.tabText(i).replace("*","") answer = QMessageBox.question(self, "Save Changes", f"Do you wish to save your changes to {name} before closing?", @@ -320,6 +321,7 @@ def close_tab(self, i: int) -> bool: val = self.handle_save_file_action() if not val: return False + widget.graph_scene.clearSelection() self.tab_widget.removeTab(i) if self.tab_widget.count() == 0: self._reset_menus(False)