Skip to content

Commit 95d2440

Browse files
committed
Refine docs on loop modes.
1 parent be7ad28 commit 95d2440

File tree

1 file changed

+49
-24
lines changed

1 file changed

+49
-24
lines changed

docs/internals.rst

Lines changed: 49 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -5,52 +5,68 @@ Under the Hood
55

66
This 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

1515
Loop 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

2828
Owner 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
3232
if 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
3637
and 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

4756
Guest 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,
5470
e.g. by calling ``app.exec()``.
5571

5672
.. note::
@@ -62,16 +78,25 @@ e.g. by calling ``app.exec()``.
6278
Native 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

77102
Interleaved code

0 commit comments

Comments
 (0)