Core¶
Running¶
- qtrio.run(async_fn, *args, done_callback=None, clock=None, instruments=())[source]¶
Run a Trio-flavored async function in guest mode on a Qt host application, and return the result.
- Parameters:
async_fn (
Callable
[...
,Awaitable
[object
]]) – The async function to run.args (
object
) – Positional arguments to pass to async_fn.done_callback (
Optional
[Callable
[[Outcomes
],None
]]) – Seeqtrio.Runner.done_callback
.clock (
Optional
[Clock
]) – Seeqtrio.Runner.clock
.instruments (
Sequence
[Instrument
]) – Seeqtrio.Runner.instruments
.
- Return type:
- Returns:
The object returned by
async_fn
.
- class qtrio.Runner(application=_Nothing.NOTHING, quit_application=True, clock=None, instruments=(), reenter=_Nothing.NOTHING, done_callback=None)[source]¶
Bases:
object
This class helps run Trio in guest mode on a Qt host application.
- application: QtGui.QGuiApplication¶
The Qt application object to run as the host. If not set before calling
run()
the application will be created asQtWidgets.QApplication(sys.argv[1:])
and.setQuitOnLastWindowClosed(False)
will be called on it to allow the application to continue throughout the lifetime of the async function passed toqtrio.Runner.run()
.
-
quit_application:
bool
¶ When true, the
done_callback()
method will quit the application when the async function passed toqtrio.Runner.run()
has completed.
-
clock:
Optional
[Clock
]¶ The clock to use for this run. This is primarily used to speed up tests that include timeouts. The value will be passed on to
trio.lowlevel.start_guest_run()
.
-
instruments:
Sequence
[Instrument
]¶ The instruments to use for this run. The value will be passed on to
trio.lowlevel.start_guest_run()
.
- reenter: qtrio.qt.Reenter¶
The
QObject
instance which will receive the events requesting execution of the needed Trio and user code in the host’s event loop and thread.
-
done_callback:
Optional
[Callable
[[Outcomes
],None
]]¶ The builtin
done_callback()
will be passed totrio.lowlevel.start_guest_run()
but will call the callback passed here before (maybe) quitting the application. Theoutcome.Outcome
from the completion of the async function passed torun()
will be passed to this callback.
-
cancel_scope:
CancelScope
¶ An all encompassing cancellation scope for the Trio execution.
- run(async_fn, *args, execute_application=True)[source]¶
Start the guest loop executing
async_fn
.- Parameters:
- Return type:
- Returns:
If
execute_application
is true, aqtrio.Outcomes
containing outcomes from the Qt application andasync_fn
will be returned. Otherwise, an emptyqtrio.Outcomes
.
- run_sync_soon_threadsafe(fn)[source]¶
Helper for the Trio guest to execute a sync function in the Qt host thread when called from the Trio guest thread. This call will not block waiting for completion of
fn
nor will it return the result of callingfn
.
- await trio_main(async_fn, args)[source]¶
Will be run as the main async function by the Trio guest. If it is a GUI application then it creates a cancellation scope to be cancelled when
lastWindowClosed
is emitted. Within this scope the application’sasync_fn
will be run and passedargs
.
- trio_done(run_outcome)[source]¶
Will be called after the Trio guest run has finished. This allows collection of the
outcome.Outcome
and execution of any application provided done callback. Finally, ifqtrio.Runner.quit_application
was set when creating the instance then the Qt application will be requested to quit.Actions such as outputting error information or unwrapping the outcomes need to be further considered.
- class qtrio.Outcomes(qt=None, trio=None)[source]¶
Bases:
object
This class holds an
outcome.Outcome
from each of the Trio and the Qt application execution. Do not construct instances directly. Instead, an instance will be returned fromqtrio.run()
or available on instances ofqtrio.Runner.outcomes
.-
qt:
Optional
[Outcome
]¶ The Qt application
outcome.Outcome
-
trio:
Optional
[Outcome
]¶ The Trio async function
outcome.Outcome
- unwrap()[source]¶
Unwrap either the Trio or Qt outcome. First, errors are given priority over success values. Second, the Trio outcome gets priority over the Qt outcome.
- Return type:
- Returns:
Whatever captured value was selected.
- Raises:
Exception – Whatever captured exception was selected.
qtrio.NoOutcomesError – if no value or exception has been captured.
-
qt:
Emissions¶
The basics of handling Qt GUIs is to respond to the widgets’ signals being emitted.
qtrio.enter_emissions_channel()
is the primary tool for handling this. It allows
for connection of signals prior to showing a window and subsequent iteration of the
emissions. See the emissions example for an example usage.
- async with qtrio.enter_emissions_channel(signals, max_buffer_size=inf)[source]¶
Create a memory channel fed by the emissions of the signals and enter both the send and receive channels’ context managers.
- Parameters:
signals (
Collection
[Signal
]) – A collection of signals which will be monitored for emissions.max_buffer_size (
Union
[int
,float
]) – When the number of unhandled emissions in the channel reaches this limit then additional emissions will be silently thrown out the window.
- Return type:
- Returns:
The emissions manager.
- class qtrio.Emission(signal, args)[source]¶
Bases:
object
Stores the emission of a signal including the emitted arguments. Can be compared against a signal instance to check the source. Do not construct this class directly. Instead, instances will be received through a channel created by
qtrio.enter_emissions_channel()
.Note
Each time you access a signal such as
a_qobject.some_signal
you get a different signal instance object so thesignal
attribute generally will not be the same object. A signal instance is aQtCore.SignalInstance
in PySide2 orQtCore.pyqtBoundSignal
in PyQt5.
- class qtrio.Emissions(channel, send_channel)[source]¶
Bases:
object
Hold elements useful for the application to work with emissions from signals. Do not construct this class directly. Instead, use
qtrio.enter_emissions_channel()
.-
channel:
MemoryReceiveChannel
¶ A memory receive channel to be fed by signal emissions.
-
send_channel:
MemorySendChannel
¶ A memory send channel collecting signal emissions.
-
channel:
If you need a more Qt-like callback mechanism qtrio.open_emissions_nursery()
offers that. Instead of tossing the callbacks behind the couch where they can leave
their errors on the floor they will be run inside a nursery.
- async with qtrio.open_emissions_nursery(until=None, wrapper=None)[source]¶
Open a nursery for handling callbacks triggered by signal emissions. This allows a ‘normal’ Qt callback structure while still executing the callbacks within a Trio nursery such that errors have a place to go. Both async and sync callbacks can be connected. Sync callbacks will be wrapped in an async call to allow execution in the nursery.
- Parameters:
- Return type:
- Returns:
The emissions manager.
- class qtrio.EmissionsNursery(nursery, exit_stack, wrapper=None)[source]¶
Bases:
object
Holds the nursery, exit stack, and wrapper needed to support connecting signals to both async and sync slots in the nursery.
-
wrapper:
Optional
[Callable
[[Callable
[...
,Awaitable
[object
]]],Awaitable
[object
]]]¶ The wrapper for handling the slots. This could, for example, handle exceptions and present a dialog to avoid cancelling the entire nursery.
-
wrapper:
Helpers¶
- class qtrio.Signal(*types, name=None)[source]¶
Bases:
object
This is a (nearly) drop-in replacement for
Signal
. The useful difference is that it does not require inheriting fromQObject
. The not-quite part is that it will be a bit more complicated to change thread affinity of the relevantQObject
. If you need this, maybe just inherit.This signal gets around the normally required inheritance by creating
QObject
instances behind the scenes to host the real signals. Just asSignal
uses the Python descriptor protocol to intercept the attribute access, so does this so it can ‘redirect’ to the signal on the other object.- object(instance)[source]¶
Get the
QObject
that hosts the real signal. This can be called such astype(instance).signal_name.object(instance)
. Yes this is non-obvious but you have to do something special to get around the descriptor protocol so you can get at this method instead of just having the underlyingSignal
.
Reentry Events¶
Generally you should not need to use these functions. If you want to have control over when the Qt event type is registered, what value it gets, or handle any exceptions raised then you may like to call these directly.
- qtrio.register_event_type()[source]¶
Register a Qt event type for use by Trio to reenter into the Qt event loop.
- Raises:
qtrio.EventTypeAlreadyRegisteredError – if an event type has already been registered.
qtrio.EventTypeRegistrationFailedError – if a type was not able to be registered.
- Return type:
- qtrio.register_requested_event_type(requested_value)[source]¶
Register the requested Qt event type for use by Trio to reenter into the Qt event loop.
- Parameters:
requested_value (
Union
[int
,Type
]) – The value to ask Qt to use for the event type being registered.- Raises:
qtrio.EventTypeAlreadyRegisteredError – if an event type has already been registered.
qtrio.EventTypeRegistrationFailedError – if a type was not able to be registered.
qtrio.RequestedEventTypeUnavailableError – if the type returned by Qt does not match the requested type.
- Return type: