diff --git a/IPython/frontend/qt/kernel_mixins.py b/IPython/frontend/qt/kernel_mixins.py index a65fc35..e97b7b6 100644 --- a/IPython/frontend/qt/kernel_mixins.py +++ b/IPython/frontend/qt/kernel_mixins.py @@ -168,6 +168,21 @@ class QtHBChannelMixin(ChannelQObject): self.kernel_died.emit(since_last_heartbeat) +class QtKernelRestarterMixin(HasTraits, SuperQObject): + + __metaclass__ = MetaQObjectHasTraits + _timer = None + + +class QtKernelManagerMixin(HasTraits, SuperQObject): + """ A KernelClient that provides signals and slots. + """ + + __metaclass__ = MetaQObjectHasTraits + + kernel_restarted = QtCore.Signal() + + class QtKernelClientMixin(HasTraits, SuperQObject): """ A KernelClient that provides signals and slots. """ diff --git a/IPython/frontend/qt/manager.py b/IPython/frontend/qt/manager.py new file mode 100644 index 0000000..4faac2b --- /dev/null +++ b/IPython/frontend/qt/manager.py @@ -0,0 +1,52 @@ +""" Defines a KernelClient that provides signals and slots. +""" + +from IPython.external.qt import QtCore + +# Local imports +from IPython.utils.traitlets import Bool, Instance + +from IPython.kernel import KernelManager +from IPython.kernel.restarter import KernelRestarter + +from .kernel_mixins import QtKernelManagerMixin, QtKernelRestarterMixin + + +class QtKernelRestarter(KernelRestarter, QtKernelRestarterMixin): + + def start(self): + if self._timer is None: + self._timer = QtCore.QTimer() + self._timer.timeout.connect(self.poll) + self._timer.start(self.time_to_dead * 1000) + + def stop(self): + self._timer.stop() + + def poll(self): + super(QtKernelRestarter, self).poll() + + +class QtKernelManager(KernelManager, QtKernelManagerMixin): + """A KernelManager with Qt signals for restart""" + + autorestart = Bool(True, config=True) + + def start_restarter(self): + if self.autorestart and self.has_kernel: + if self._restarter is None: + self._restarter = QtKernelRestarter( + kernel_manager=self, + config=self.config, + log=self.log, + ) + self._restarter.register_callback(self._handle_kernel_restarted) + self._restarter.start() + + def stop_restarter(self): + if self.autorestart: + if self._restarter is not None: + self._restarter.stop() + + def _handle_kernel_restarted(self): + self.kernel_restarted.emit()