Close app on last window exit

Use a system triggered SIGINT on app close to tear down the streaming
stack and terminate the `trio`/`tractor` runtimes deterministically.
to_qpainterpath_and_beyond
Tyler Goodlet 2020-12-13 13:11:23 -05:00
parent 599b5276b4
commit 9930430721
1 changed files with 17 additions and 8 deletions

View File

@ -20,6 +20,8 @@ Trio - Qt integration
Run ``trio`` in guest mode on top of the Qt event loop. Run ``trio`` in guest mode on top of the Qt event loop.
All global Qt runtime settings are mostly defined here. All global Qt runtime settings are mostly defined here.
""" """
import os
import signal
from functools import partial from functools import partial
import traceback import traceback
from typing import Tuple, Callable, Dict, Any from typing import Tuple, Callable, Dict, Any
@ -74,11 +76,16 @@ class MainWindow(QtGui.QMainWindow):
self.setMinimumSize(*self.size) self.setMinimumSize(*self.size)
self.setWindowTitle(self.title) self.setWindowTitle(self.title)
def closeEvent(self, event: 'QCloseEvent') -> None: def closeEvent(
self,
event: 'QCloseEvent'
) -> None:
"""Cancel the root actor asap. """Cancel the root actor asap.
""" """
tractor.current_actor().cancel_soon() # raising KBI seems to get intercepted by by Qt so just use the
# system.
os.kill(os.getpid(), signal.SIGINT)
def run_qtractor( def run_qtractor(
@ -128,10 +135,14 @@ def run_qtractor(
def done_callback(outcome): def done_callback(outcome):
print(f"Outcome: {outcome}")
if isinstance(outcome, Error): if isinstance(outcome, Error):
exc = outcome.error exc = outcome.error
if isinstance(outcome.error, KeyboardInterrupt):
# make it look like ``trio``
print("Aborted!")
else:
traceback.print_exception(type(exc), exc, exc.__traceback__) traceback.print_exception(type(exc), exc, exc.__traceback__)
app.quit() app.quit()
@ -144,9 +155,6 @@ def run_qtractor(
instance = main_widget() instance = main_widget()
instance.window = window instance.window = window
# kill the app when root actor terminates
tractor._actor._lifetime_stack.callback(app.quit)
widgets = { widgets = {
'window': window, 'window': window,
'main': instance, 'main': instance,
@ -170,6 +178,7 @@ def run_qtractor(
main, main,
run_sync_soon_threadsafe=run_sync_soon_threadsafe, run_sync_soon_threadsafe=run_sync_soon_threadsafe,
done_callback=done_callback, done_callback=done_callback,
# restrict_keyboard_interrupt_to_checkpoints=True,
) )
window.main_widget = main_widget window.main_widget = main_widget