Traits Futures: reactive background processing for Traits and TraitsUI¶
Release v0.1.1.
The traits_futures
package provides a means to fire off a background
calculation from a TraitsUI application, and later respond to the result(s)
of that calculation, leaving the main UI responsive for user interactions while
the background calculation is in progress.
Features¶
- Supports simple calls, iterations, and progress-reporting functions. Can easily be extended to support other messaging patterns.
- Dispatching a background task returns a “future” object, which provides:
- information about state changes (e.g., background task completion)
- facilities to (cooperatively) cancel a long-running background task
- access to result(s) arriving from the background task
- Future objects are
HasTraits
instances, suitable for integration into a TraitsUI application. - No need to be a threading expert! Incoming results arrive as trait changes in the main thread. This eliminates a large class of potential issues with traditional thread-based solutions (race conditions, deadlocks, and UI updates off the main thread).
- Cross-platform, and compatible with both Python 2 and Python 3.
Limitations¶
- By design, and unlike concurrent_futures,
traits_futures
requires the UI event loop to be running in order to process results. - For the moment,
traits_futures
requires Qt. Support for wxPython may arrive in a future release. - No multiprocessing support yet. Maybe one day.
Quick start¶
Here’s a complete example showing a minimal TraitsUI application that fires off a background computation when its “Calculate” button is pressed, and shows the result when it arrives.
# (C) Copyright 2018-2019 Enthought, Inc., Austin, TX
# All rights reserved.
import time
from traits.api import Button, HasTraits, Instance, Int, on_trait_change, Str
from traitsui.api import Item, View
from traits_futures.api import CallFuture, TraitsExecutor
# The target function that we plan to execute in the background.
def slow_square(n):
""" Square the given input, slowly. """
time.sleep(2.0)
return n * n
class QuickStartExample(HasTraits):
#: The executor to submit tasks to.
executor = Instance(TraitsExecutor, ())
#: The future object returned on task submission.
future = Instance(CallFuture)
#: Input for the calculation.
input = Int(10)
#: Result, in string form.
result = Str("No result yet")
#: Button to start the calculation.
calculate = Button()
@on_trait_change("calculate")
def _submit_background_call(self):
# Returns immediately.
self.future = self.executor.submit_call(slow_square, self.input)
@on_trait_change("future:done")
def _report_result(self, future, name, done):
self.result = "Square is {}".format(future.result)
traits_view = View(
Item("input"),
Item("result", style="readonly"),
Item("calculate", enabled_when="future is None or future.done"),
)
QuickStartExample().configure_traits()
Detailed Documentation¶
- User guide
- API documentation
- traits_futures package
- traits_futures.qt package
- traits_futures.api module
- traits_futures.background_call module
- traits_futures.background_iteration module
- traits_futures.background_progress module
- traits_futures.exception_handling module
- traits_futures.future_states module
- traits_futures.toolkit_support module
- traits_futures.traits_executor module
- traits_futures.version module
- traits_futures package