@@ -5,52 +5,68 @@ Under the Hood
55
66This page explains how :mod: `qtinter ` is implemented.
77
8- We first give an overview of how `` asyncio `` works. We then give an
9- overview of how Qt works. We then explain how :mod: ` qtinter ` bridges
10- them .
8+ We first give an overview of how :external:mod: ` asyncio ` works.
9+ We then give an overview of how Qt works. We then explain how
10+ :mod: ` qtinter ` bridges the two .
1111
1212
1313.. _loop-modes :
1414
1515Loop modes
1616----------
1717
18- A :class: `qtinter. QiBaseEventLoop ` has three *modes * of operations:
18+ A :class: `QiBaseEventLoop ` has three *modes of operations * :
1919*owner mode *, *guest mode *, and *native mode *.
2020
2121.. note ::
2222
2323 Both owner mode and guest mode require a ``QtCore.QCoreApplication ``,
2424 ``QtGui.QGuiApplication `` or ``QtWidgets.QApplication `` instance to
2525 exist in order to run the loop. This is because these modes use Qt's
26- signals and slots to schedule callbacks.
26+ signal-slot mechanism to schedule callbacks.
2727
2828Owner mode
2929~~~~~~~~~~
3030
31- *Owner mode * provides 100% asyncio loop semantics and should be used
31+ *Owner mode * provides 100% asyncio event loop semantics. It should be used
3232if your code calls :func: `asyncio.run ` or equivalent as its entry point.
33- You normally launch a loop in host mode using the
34- :func: `qtinter.using_qt_from_asyncio ` context manager. Alternatively,
35- call :func: `qtinter.default_loop_factory ` to create a loop in host mode
33+
34+ You normally launch a :class: `QiBaseEventLoop ` in host mode using the
35+ :func: `using_qt_from_asyncio ` context manager. Alternatively, call
36+ :func: `new_event_loop ` to create a :class: `QiBaseEventLoop ` in host mode
3637and then manipulate it manually.
3738
3839.. note ::
3940
40- :class: `qtinter. QiBaseEventLoop ` runs a ``QtCore.QEventLoop `` when
41+ :class: `QiBaseEventLoop ` executes a ``QtCore.QEventLoop `` when
4142 operating in owner mode. If a Qt event loop is already running,
42- the loop will be nested, which is not recommended. Also, after
43- ``QtCore.QCoreApplication.exit() `` is called, it is no longer
44- possible to start a ``QtCore.QEventLoop ``, and hence not possible
45- to run a :class: `qtinter.QiBaseEventLoop ` in owner mode.
43+ the new loop will run nested, which may cause the usual subtle
44+ consequences with nested loops and therefore is not recommended.
45+ If you already have a Qt event loop running and want to use asyncio
46+ functionalities, use the :func: `using_asyncio_from_qt ` context
47+ manager instead.
48+
49+ .. note ::
50+
51+ If ``QtCore.QCoreApplication.exit() `` has been called, it will be
52+ no longer possible to start a ``QtCore.QEventLoop `` and hence not
53+ possible to run a :class: `QiBaseEventLoop ` in owner mode. You
54+ may run the :class: `QiBaseEventLoop ` in native mode if needed.
4655
4756Guest mode
4857~~~~~~~~~~
4958
50- *Guest mode * is designed for Qt-driven code, and is normally activated
51- using the :func: `qtinter.using_asyncio_from_qt ` context manager.
52- In guest mode, only a *logical * asyncio event loop is activated; the
53- *physical * Qt event loop must still be run by the application code,
59+ *Guest mode * runs a *logical * asyncio event loop on top of a *physical *
60+ Qt event loop. It is designed to enable asyncio access for Qt-driven
61+ code.
62+
63+ Guest mode is normally activated using the :func: `using_asyncio_from_qt `
64+ context manager. Under the hood, the context manager calls
65+ :func: `new_event_loop ` to create a :class: `QiBaseEventLoop ` object
66+ and then calls its :meth: `QiBaseEventLoop.set_mode ` method with
67+ argument :data: `QiLoopMode.GUEST `.
68+
69+ The physical Qt event loop must be run by the application code,
5470e.g. by calling ``app.exec() ``.
5571
5672.. note ::
@@ -62,16 +78,25 @@ e.g. by calling ``app.exec()``.
6278Native mode
6379~~~~~~~~~~~
6480
65- *Native mode * is activated when :external:meth: `asyncio.loop.run_forever `
66- is called on a :class: `qtinter.QiBaseEventLoop ` object operating in guest
67- mode. In native mode, a native asyncio event loop is run, and no
68- Qt event loop is used at all. This is designed for running clean-up code,
69- possibly after ``QtCore.QCoreApplication.exec `` has been called.
81+ A :class: `QiBaseEventLoop ` in *native mode * runs a *physical * asyncio
82+ event loop and behaves exactly like a standard asyncio event loop;
83+ no Qt functionality is involved.
84+
85+ Native mode is activated by the :func: `using_asyncio_from_qt ` context
86+ manager in its clean-up code before running the coroutines to cancel
87+ pending tasks and shutdown async generators. This mode allows
88+ coroutines to run even after ``QtCore.QCoreApplication.exec ``
89+ has been called.
90+
91+ To manually activate native mode, call :meth: `QiBaseEventLoop.set_mode `
92+ with argument :data: `QiLoopMode.NATIVE `.
7093
7194.. note ::
7295
7396 Because no Qt event loop is running in native mode, you should not
74- use any Qt objects in clean-up code.
97+ use any Qt objects in this mode. In particular, the clean-up code
98+ in your coroutines should work without requiring a running Qt event
99+ loop.
75100
76101
77102Interleaved code
0 commit comments