diff --git a/spyder/api/widgets/status.py b/spyder/api/widgets/status.py index afb5a9c5961..9c1bc35aeec 100644 --- a/spyder/api/widgets/status.py +++ b/spyder/api/widgets/status.py @@ -218,6 +218,10 @@ def __init__(self, parent=None): self.timer.timeout.connect(self.update_status) self.timer.start(self._interval) + def closeEvent(self, event): + self.timer.stop() + super().closeEvent(event) + # ---- Qt API def setVisible(self, value): """Override Qt method to stops timers if widget is not visible.""" diff --git a/spyder/app/mainwindow.py b/spyder/app/mainwindow.py index 66b7aa96acc..1d9bcb77aa1 100644 --- a/spyder/app/mainwindow.py +++ b/spyder/app/mainwindow.py @@ -1458,6 +1458,7 @@ def set_splash(self, message): def closeEvent(self, event): """closeEvent reimplementation""" if self.closing(True): + QApplication.processEvents() event.accept() else: event.ignore() diff --git a/spyder/app/tests/test_mainwindow.py b/spyder/app/tests/test_mainwindow.py index b769dc1d04e..de88604c8d2 100644 --- a/spyder/app/tests/test_mainwindow.py +++ b/spyder/app/tests/test_mainwindow.py @@ -352,7 +352,7 @@ def main_window(request, tmpdir, qtbot): if client.info_page != client.blank_page: print('info_page') print(client.info_page) - window.closing(cancelable=False, close_immediately=True) + # window.closing(cancelable=False, close_immediately=True) window.close() del main_window.window else: diff --git a/spyder/plugins/editor/widgets/status.py b/spyder/plugins/editor/widgets/status.py index 18077c94d33..2605bdd2e0b 100644 --- a/spyder/plugins/editor/widgets/status.py +++ b/spyder/plugins/editor/widgets/status.py @@ -91,8 +91,8 @@ def __init__(self, parent): # ---- Qt reimplemented def closeEvent(self, event): - self._worker_manager.terminate_all() super().closeEvent(event) + self._worker_manager.terminate_all() def update_vcs_state(self, idx, fname, fname2): """Update vcs status.""" @@ -114,7 +114,7 @@ def update_vcs(self, fname, index, force=False): self._last_git_job = (fname, index) self._git_job_queue = None self._git_is_working = True - #worker.start() + worker.start() def get_git_refs(self, fname): """Get Git active branch, state, branches (plus tags).""" diff --git a/spyder/plugins/editor/widgets/tests/conftest.py b/spyder/plugins/editor/widgets/tests/conftest.py index b48733b98a3..68a2f5e2f31 100644 --- a/spyder/plugins/editor/widgets/tests/conftest.py +++ b/spyder/plugins/editor/widgets/tests/conftest.py @@ -227,9 +227,9 @@ def codeeditor(qtbot): scroll_past_end=True) widget.setup_editor(language='Python') widget.resize(640, 480) - qtbot.addWidget(widget) widget.show() - return widget + yield widget + widget.close() @pytest.fixture diff --git a/spyder/plugins/ipythonconsole/tests/test_ipythonconsole.py b/spyder/plugins/ipythonconsole/tests/test_ipythonconsole.py index 21b4a70bbe5..0dcd5d457d6 100644 --- a/spyder/plugins/ipythonconsole/tests/test_ipythonconsole.py +++ b/spyder/plugins/ipythonconsole/tests/test_ipythonconsole.py @@ -204,9 +204,6 @@ def __getattr__(self, attr): # Set exclamation mark to True configuration.set('ipython_console', 'pdb_use_exclamation_mark', True) - # This segfaults on macOS - if not sys.platform == "darwin": - qtbot.addWidget(window) window.resize(640, 480) window.show() diff --git a/spyder/plugins/ipythonconsole/widgets/main_widget.py b/spyder/plugins/ipythonconsole/widgets/main_widget.py index 1150b9e4b67..b298e547506 100644 --- a/spyder/plugins/ipythonconsole/widgets/main_widget.py +++ b/spyder/plugins/ipythonconsole/widgets/main_widget.py @@ -373,6 +373,10 @@ def __init__(self, name=None, plugin=None, parent=None, # See spyder-ide/spyder#11880 self._init_asyncio_patch() + def on_close(self): + self.mainwindow_close = True + self.close_clients() + # ---- PluginMainWidget API and settings handling # ------------------------------------------------------------------------ def get_title(self): diff --git a/spyder/plugins/maininterpreter/container.py b/spyder/plugins/maininterpreter/container.py index 77d78011cf7..a84e687852d 100644 --- a/spyder/plugins/maininterpreter/container.py +++ b/spyder/plugins/maininterpreter/container.py @@ -63,6 +63,9 @@ def section_conf_update(self, option, value): osp.isfile(executable)): self.sig_add_to_custom_interpreters_requested.emit(executable) + def on_close(self): + self.interpreter_status.close() + # ---- Public API def get_main_interpreter(self): if self.get_conf('default'): diff --git a/spyder/plugins/maininterpreter/widgets/status.py b/spyder/plugins/maininterpreter/widgets/status.py index 67b18bf46c1..b402b70721e 100644 --- a/spyder/plugins/maininterpreter/widgets/status.py +++ b/spyder/plugins/maininterpreter/widgets/status.py @@ -108,6 +108,7 @@ def get_icon(self): # ---- Qt reimplemented def closeEvent(self, event): + self._get_envs_timer.stop() self._worker_manager.terminate_all() super().closeEvent(event) diff --git a/spyder/plugins/onlinehelp/tests/test_pydocgui.py b/spyder/plugins/onlinehelp/tests/test_pydocgui.py index 8c420b43886..f4505554726 100644 --- a/spyder/plugins/onlinehelp/tests/test_pydocgui.py +++ b/spyder/plugins/onlinehelp/tests/test_pydocgui.py @@ -27,14 +27,12 @@ def pydocbrowser(qtbot): plugin_mock = MagicMock() plugin_mock.CONF_SECTION = 'onlinehelp' widget = PydocBrowser(parent=None, plugin=plugin_mock, name='pydoc') - qtbot.addWidget(widget) - widget._setup() - widget.setup() - widget.resize(640, 480) - widget.show() - with qtbot.waitSignal(widget.sig_load_finished, timeout=20000): - widget.initialize() + widget._setup() + widget.setup() + widget.resize(640, 480) + widget.show() + widget.initialize(force=True) yield widget widget.close() diff --git a/spyder/plugins/onlinehelp/widgets.py b/spyder/plugins/onlinehelp/widgets.py index 8db578a00e6..897ea5172c0 100644 --- a/spyder/plugins/onlinehelp/widgets.py +++ b/spyder/plugins/onlinehelp/widgets.py @@ -123,8 +123,6 @@ def quit_server(self): if self.server.serving: self.server.stop() - self.quit() - self.wait() class PydocBrowser(PluginMainWidget): @@ -297,16 +295,9 @@ def _handle_icon_change(self): # --- Qt overrides # ------------------------------------------------------------------------ def closeEvent(self, event): - # Process pending event before closing. - # Prevents showing warnings regarding WebEnginePage not being deleted: - # `Release of profile requested but WebEnginePage still not deleted. - # Expect troubles !` - QApplication.processEvents() - try: - self.server.quit_server() - except AttributeError: - pass - event.accept() + self.webview.web_widget.stop() + self.quit_server() + super().closeEvent(event) # --- Public API # ------------------------------------------------------------------------ @@ -322,7 +313,7 @@ def load_history(self, history): self.url_combo.addItems(history) @Slot(bool) - def initialize(self, checked=True): + def initialize(self, checked=True, force=False): """ Start pydoc server. @@ -332,11 +323,14 @@ def initialize(self, checked=True): This method is connected to the `sig_toggle_view_changed` signal, so that the first time the widget is made visible it will start the server. Default is True. + force: bool, optional + Force a server start even if the server is running. + Default is False. """ - if checked and self.server is None: + if force or (checked and self.server is None + or not self.server.is_running()): self.sig_toggle_view_changed.disconnect(self.initialize) QApplication.setOverrideCursor(QCursor(Qt.WaitCursor)) - QApplication.processEvents() self.start_server() def is_server_running(self): @@ -347,10 +341,11 @@ def start_server(self): """Start pydoc server.""" if self.server is None: self.set_home_url('http://127.0.0.1:{}/'.format(PORT)) - elif self.server.isRunning(): + elif self.server.is_running(): self.server.sig_server_started.disconnect( self._continue_initialization) self.server.quit() + self.server.wait() self.server = PydocServer(self, port=PORT) self.server.sig_server_started.connect( @@ -367,6 +362,7 @@ def quit_server(self): self._continue_initialization) self.server.quit_server() self.server.quit() + self.server.wait() def get_label(self): """Return address label text""" diff --git a/spyder/plugins/projects/utils/watcher.py b/spyder/plugins/projects/utils/watcher.py index 49d3994aeb7..218a1ab0507 100644 --- a/spyder/plugins/projects/utils/watcher.py +++ b/spyder/plugins/projects/utils/watcher.py @@ -108,8 +108,8 @@ class WorkspaceWatcher(QObject): """ def __init__(self, parent=None): - super().__init__(parent) self.observer = None + super().__init__(parent) self.event_handler = WorkspaceEventHandler(self) def connect_signals(self, project): @@ -131,6 +131,7 @@ def start(self, workspace_folder): # This error happens frequently on Linux logger.debug("Watcher could not be started.") except OSError as e: + self.observer = None if u'inotify' in to_text_string(e): QMessageBox.warning( self.parent(), @@ -152,7 +153,6 @@ def start(self, workspace_folder): "

" "After doing that, you need to close and start Spyder " "again so those changes can take effect.")) - self.observer = None else: raise e