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
Return type

object

Returns

The object returned by async_fn.

class qtrio.Runner(application=NOTHING, quit_application=True, clock=None, instruments=(), reenter=NOTHING, done_callback=None)[source]

Bases: object

This class helps run Trio in guest mode on a Qt host application.

application: QGuiApplication

The Qt application object to run as the host. If not set before calling run() the application will be created as QtWidgets.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 to qtrio.Runner.run().

quit_application: bool

When true, the done_callback() method will quit the application when the async function passed to qtrio.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 to trio.lowlevel.start_guest_run() but will call the callback passed here before (maybe) quitting the application. The outcome.Outcome from the completion of the async function passed to run() will be passed to this callback.

outcomes: Outcomes

The outcomes from the Qt and Trio runs.

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
  • async_fn (Callable[..., Awaitable[object]]) – The async function to be run in the Qt host loop by the Trio guest.

  • args (object) – Arguments to pass when calling async_fn.

  • execute_application (bool) – If True, the Qt application will be executed and this call will block until it finishes.

Return type

Outcomes

Returns

If execute_application is true, a qtrio.Outcomes containing outcomes from the Qt application and async_fn will be returned. Otherwise, an empty qtrio.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 calling fn.

Parameters

fn (Callable[[], object]) – A no parameter callable.

Return type

None

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’s async_fn will be run and passed args.

Parameters
  • async_fn (Callable[..., Awaitable[object]]) – The application’s main async function to be run by Trio in the Qt host’s thread.

  • args (Tuple[object, ...]) – Positional arguments to be passed to async_fn

Return type

object

Returns

The result returned by async_fn.

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, if qtrio.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.

Parameters

run_outcome (Outcome) – The outcome of the Trio guest run.

Return type

None

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 from qtrio.run() or available on instances of qtrio.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

object

Returns

Whatever captured value was selected.

Raises

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

AsyncGenerator[Emissions, None]

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 the signal attribute generally will not be the same object. A signal instance is a QtCore.SignalInstance in PySide2 or QtCore.pyqtBoundSignal in PyQt5.

signal: Signal

An instance of the original signal.

args: Tuple[object, ...]

A tuple of the arguments emitted by the signal.

is_from(signal)[source]

Check if this emission came from signal.

Parameters

signal (Signal) – The signal instance to check for being the source.

Return type

bool

Returns

Whether the passed signal was the source of this emission.

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.

await aclose()[source]

Asynchronously close the send channel when signal emissions are no longer of interest.

Return type

None

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

AsyncGenerator[EmissionsNursery, None]

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.

nursery: Nursery

The Trio nursery that will handle execution of the slots.

exit_stack: ExitStack

The exit stack that will manage the connections so they get disconnected.

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.

connect(signal, slot)[source]

Connect an async signal to this emissions nursery so when called the slot will be run in the nursery.

Return type

None

connect_sync(signal, slot)[source]

Connect to a sync slot to this emissions nursery so when called the slot will be run in the nursery.

Return type

None

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 from QObject. The not-quite part is that it will be a bit more complicated to change thread affinity of the relevant QObject. 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 as Signal 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 as type(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 underlying Signal.

Parameters

instance (object) – The object on which this descriptor instance is hosted.

Return type

QObject

Returns

The signal-hosting QObject.

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
Return type

None

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
Return type

None

qtrio.registered_event_type()[source]

Get the registered event type.

Return type

Optional[Type]

Returns

The type registered with Qt for the reenter event. None if no event type has been registered yet.