psygnal.containers #
Containers backed by psygnal events.
These classes provide "evented" versions of mutable python containers. They each have an events attribute (SignalGroup) that has a variety of signals that will emit whenever the container is mutated. See Container SignalGroups for the corresponding container type for details on the available signals.
Classes:
-
CallableProxyEvents–Events emitted by
EventedCallableObjectProxy. -
DictEvents–Events available on EventedDict.
-
EventedCallableObjectProxy–Create a proxy of
targetthat includes aneventspsygnal.SignalGroup. -
EventedDict–Mutable mapping that emits events when altered.
-
EventedList–Mutable Sequence that emits events when altered.
-
EventedObjectProxy–Create a proxy of
targetthat includes aneventspsygnal.SignalGroup. -
EventedOrderedSet–A ordered variant of EventedSet that maintains insertion order.
-
EventedSet–A set with an
items_changedsignal that emits when items are added/removed. -
ListEvents–Events available on EventedList.
-
OrderedSet–A set that preserves insertion order, uses dict behind the scenes.
-
ProxyEvents–Events emitted by
EventedObjectProxyandEventedCallableObjectProxy. -
SelectableEventedList–EventedListsubclass with a built in selection model. -
Selection–An model of selected items, with a
activeandcurrentitem. -
SetEvents–Events available on EventedSet.
CallableProxyEvents #
CallableProxyEvents(instance: Any = None)
Bases: ProxyEvents
Events emitted by EventedCallableObjectProxy.
Attributes:
-
called–Emitted when the object is called.
Source code in src/psygnal/_group.py
429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 | |
called class-attribute instance-attribute #
called = Signal(tuple, dict)
Emitted when the object is called.
DictEvents #
DictEvents(instance: Any = None)
Bases: SignalGroup
Events available on EventedDict.
Attributes:
-
added–(key, value)emitted after avalueis added atkey -
adding–(key,)emitted before an item is added atkey -
changed–(key, old_value, new_value)emitted beforeold_valueis replaced with -
changing–(key, old_value, new_value)emitted beforeold_valueis replaced with -
removed–(key, value)emitted aftervalueis removed atkey -
removing–(key,)emitted before an item is removed atkey
Source code in src/psygnal/_group.py
429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 | |
added class-attribute instance-attribute #
added = DictSignal(object, object)
(key, value) emitted after a value is added at key
adding class-attribute instance-attribute #
adding = DictSignal(object)
(key,) emitted before an item is added at key
changed class-attribute instance-attribute #
changed = DictSignal(object, object, object)
(key, old_value, new_value) emitted before old_value is replaced with new_value at key
changing class-attribute instance-attribute #
changing = DictSignal(object)
(key, old_value, new_value) emitted before old_value is replaced with new_value at key
removed class-attribute instance-attribute #
removed = DictSignal(object, object)
(key, value) emitted after value is removed at key
removing class-attribute instance-attribute #
removing = DictSignal(object)
(key,) emitted before an item is removed at key
EventedCallableObjectProxy #
EventedCallableObjectProxy(target: Callable)
Bases: EventedObjectProxy
Create a proxy of target that includes an events psygnal.SignalGroup.
target must be callable.
Important
This class requires wrapt to be installed. You can install directly (pip install wrapt) or by using the psygnal extra: pip install psygnal[proxy]
Signals will be emitted whenever an attribute is set or deleted, or (if the object implements __getitem__) whenever an item is set or deleted. If the object supports in-place modification (i.e. any of the __i{}__ magic methods), then an in_place event is emitted (with the name of the method) whenever any of them are used. Lastly, if the item is called, a called event is emitted with the (args, kwargs) used in the call.
The events available at target.events include:
attribute_set:Signal(str, object)attribute_deleted:Signal(str)item_set:Signal(object, object)item_deleted:Signal(object)in_place:Signal(str, object)called:Signal(tuple, dict)
Parameters:
Attributes:
-
events(CallableProxyEvents) –SignalGroupcontaining events for this object proxy.
Source code in src/psygnal/containers/_evented_proxy.py
215 216 | |
EventedDict #
EventedDict(
data: DictArg | None = None,
*,
basetype: TypeOrSequenceOfTypes = (),
**kwargs: _V,
)
Bases: TypedMutableMapping[_K, _V]
Mutable mapping that emits events when altered.
This class is designed to behave exactly like the builtin dict, but will emit events before and after all mutations (addition, removal, and changing).
Parameters:
-
(data#Union[Mapping[_K, _V], Iterable[Tuple[_K, _V]], None], default:None) –Data suitable of passing to dict(). Mapping of {key: value} pairs, or Iterable of two-tuples [(key, value), ...], or None to create an
-
(basetype#TypeOrSequenceOfTypes, default:()) –Type or Sequence of Type objects. If provided, values entered into this Mapping must be an instance of one of the provided types. by default ().
Attributes:
-
events(DictEvents) –The
SignalGroupobject that emits all events available on anEventedDict.
Source code in src/psygnal/containers/_evented_dict.py
186 187 188 189 190 191 192 193 194 | |
EventedList #
EventedList(
data: Iterable[_T] = (),
*,
hashable: bool = True,
child_events: bool = True,
)
Bases: MutableSequence[_T]
Mutable Sequence that emits events when altered.
This class is designed to behave exactly like the builtin list, but will emit events before and after all mutations (insertion, removal, setting, and moving).
Parameters:
-
(data#iterable, default:()) –Elements to initialize the list with.
-
(hashable#bool, default:True) –Whether the list should be hashable as id(self). By default
True. -
(child_events#bool, default:True) –Whether to re-emit events from emitted from evented items in the list (i.e. items that have SignalInstances). If
True, child events can be connected atEventedList.events.child_event. By default,True.
Attributes:
-
events(ListEvents) –SignalGroup that with events related to list mutation. (see ListEvents)
Methods:
-
clear–Remove all items from the list.
-
copy–Return a shallow copy of the list.
-
extend–Extend list by appending all items from
values. -
insert–Insert
valuebefore index. -
move–Insert object at
src_indexbeforedest_index. -
move_multiple–Move a batch of
sourcesindices, to a single destination. -
reverse–Reverse list IN PLACE.
Source code in src/psygnal/containers/_evented_list.py
181 182 183 184 185 186 187 188 189 190 191 192 193 | |
clear #
clear() -> None
Remove all items from the list.
Overrides MutableSequence.clear (which pops one at a time) so the whole list is removed as a single contiguous block (one batch_removing/ batch_removed pair). Items still go through __delitem__, so the per-item removing/removed events fire for each, highest index first, as before.
Source code in src/psygnal/containers/_evented_list.py
253 254 255 256 257 258 259 260 261 262 | |
copy #
copy() -> Self
Return a shallow copy of the list.
Source code in src/psygnal/containers/_evented_list.py
354 355 356 | |
extend #
extend(values: Iterable[_T]) -> None
Extend list by appending all items from values.
Overrides MutableSequence.extend (which appends one at a time) so the whole batch is bracketed by a single batch_inserting/batch_inserted pair. Items still go through insert one by one, emitting the per-item events.
Source code in src/psygnal/containers/_evented_list.py
220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 | |
insert #
insert(index: int, value: _T) -> None
Insert value before index.
Source code in src/psygnal/containers/_evented_list.py
202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 | |
move #
move(src_index: int, dest_index: int = 0) -> bool
Insert object at src_index before dest_index.
Both indices refer to the list prior to any object removal (pre-move space).
Source code in src/psygnal/containers/_evented_list.py
416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 | |
move_multiple #
move_multiple(
sources: Iterable[Index], dest_index: int = 0
) -> int
Move a batch of sources indices, to a single destination.
Note, if dest_index is higher than any of the sources, then the resulting position of the moved objects after the move operation is complete will be lower than dest_index.
Parameters:
-
(sources#Iterable[Union[int, slice]]) –A sequence of indices
-
(dest_index#int, default:0) –The destination index. All sources will be inserted before this index (in pre-move space), by default 0... which has the effect of "bringing to front" everything in
sources, or acting as a "reorder" method ifsourcescontains all indices.
Returns:
-
int–The number of successful move operations completed.
Raises:
-
TypeError–If the destination index is a slice, or any of the source indices are not
intorslice.
Source code in src/psygnal/containers/_evented_list.py
437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 | |
reverse #
reverse(*, emit_individual_events: bool = False) -> None
Reverse list IN PLACE.
Parameters:
-
(emit_individual_events#bool, default:False) –If True, the list is reversed one item at a time, emitting per-item events; otherwise the underlying data is reversed directly, by default False
Source code in src/psygnal/containers/_evented_list.py
400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 | |
EventedObjectProxy #
EventedObjectProxy(target: Any)
Bases: ObjectProxy, Generic[T]
Create a proxy of target that includes an events psygnal.SignalGroup.
Provides an "evented" subclasses of wrapt.ObjectProxy
Important
This class requires wrapt to be installed. You can install directly (pip install wrapt) or by using the psygnal extra: pip install psygnal[proxy]
Signals will be emitted whenever an attribute is set or deleted, or (if the object implements __getitem__) whenever an item is set or deleted. If the object supports in-place modification (i.e. any of the __i{}__ magic methods), then an in_place event is emitted (with the name of the method) whenever any of them are used.
The events available at target.events include:
attribute_set:Signal(str, object)attribute_deleted:Signal(str)item_set:Signal(object, object)item_deleted:Signal(object)in_place:Signal(str, object)
Experimental
This object is experimental! They may affect the behavior of the wrapped object in unanticipated ways. Please consult the wrapt documentation for details on how the Object Proxy works.
Parameters:
Attributes:
-
events(ProxyEvents) –SignalGroupcontaining events for this object proxy.
Source code in src/psygnal/containers/_evented_proxy.py
89 90 | |
EventedOrderedSet #
EventedOrderedSet(iterable: Iterable[_T] = ())
Bases: EventedSet, OrderedSet[_T]
A ordered variant of EventedSet that maintains insertion order.
Parameters:
-
(iterable#Iterable[_T], default:()) –Data to populate the set. If omitted, an empty set is created.
Attributes:
-
events(SetEvents) –SignalGroup that with events related to set mutation. (see SetEvents)
Source code in src/psygnal/containers/_evented_set.py
361 362 | |
EventedSet #
EventedSet(iterable: Iterable[_T] = ())
Bases: _BaseMutableSet[_T]
A set with an items_changed signal that emits when items are added/removed.
Parameters:
-
(iterable#Iterable[_T], default:()) –Data to populate the set. If omitted, an empty set is created.
Attributes:
-
events(SetEvents) –SignalGroup that with events related to set mutation. (see SetEvents)
Examples:
>>> from psygnal.containers import EventedSet
>>>
>>> my_set = EventedSet([1, 2, 3])
>>> my_set.events.items_changed.connect(
>>> lambda a, r: print(f"added={a}, removed={r}")
>>> )
>>> my_set.update({3, 4, 5})
added=(4, 5), removed=()
Multi-item events will be reduced into a single emission:
>>> my_set.symmetric_difference_update({4, 5, 6, 7})
added=(6, 7), removed=(4, 5)
>>> my_set
EventedSet({1, 2, 3, 6, 7})
Methods:
-
clear–Remove all elements from this set.
-
difference_update–Remove all elements of another set from this set.
-
intersection_update–Update this set with the intersection of itself and another.
-
symmetric_difference_update–Update this set with the symmetric difference of itself and another.
-
update–Update this set with the union of this set and others.
Source code in src/psygnal/containers/_evented_set.py
286 287 288 | |
clear #
clear() -> None
Remove all elements from this set.
Source code in src/psygnal/containers/_evented_set.py
295 296 297 298 | |
difference_update #
difference_update(*s: Iterable[_T]) -> None
Remove all elements of another set from this set.
Source code in src/psygnal/containers/_evented_set.py
300 301 302 303 | |
intersection_update #
intersection_update(*s: Iterable[_T]) -> None
Update this set with the intersection of itself and another.
Source code in src/psygnal/containers/_evented_set.py
305 306 307 308 | |
symmetric_difference_update #
symmetric_difference_update(__s: Iterable[_T]) -> None
Update this set with the symmetric difference of itself and another.
This will remove any items in this set that are also in other, and add any items in others that are not present in this set.
Source code in src/psygnal/containers/_evented_set.py
310 311 312 313 314 315 316 317 | |
update #
update(*others: Iterable[_T]) -> None
Update this set with the union of this set and others.
Source code in src/psygnal/containers/_evented_set.py
290 291 292 293 | |
ListEvents #
ListEvents(instance: Any = None)
Bases: SignalGroup
Events available on EventedList.
Attributes:
-
batch_inserted–(start, stop, values)emitted once after a contiguous block of items has been -
batch_inserting–(start, stop)emitted once before a contiguous block of items is inserted -
batch_removed–(start, stop, values)emitted once after a contiguous block of items has been -
batch_removing–(start, stop)emitted once before a contiguous block of items is removed from -
changed–(index_or_slice, old_value, value)emitted whenindexis set from -
child_event–(EmissionInfo)emitted when an object in the list emits an -
inserted–(index, value)emitted aftervalueis inserted atindex -
inserting–(index)emitted before an item is inserted atindex -
moved–(index, new_index, value)emitted aftervalueis moved from -
moving–(index, new_index)emitted before an item is moved fromindexto -
removed–(index, value)emitted aftervalueis removed atindex -
removing–(index)emitted before an item is removed atindex -
reordered–Emitted when the list is reordered (eg. moved/reversed).
Source code in src/psygnal/_group.py
429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 | |
batch_inserted class-attribute instance-attribute #
batch_inserted = ListSignal(int, int, object)
(start, stop, values) emitted once after a contiguous block of items has been inserted into the half-open range [start, stop) (values is the inserted list).
insert always pairs this with its batch_inserting. extend does too, unless _pre_insert rejects a value part way through the batch, in which case the exception propagates and the batch is left unterminated (the list is partially extended, as it is without the batch signals).
batch_inserting class-attribute instance-attribute #
batch_inserting = ListSignal(int, int)
(start, stop) emitted once before a contiguous block of items is inserted into the half-open range [start, stop).
This brackets the per-item inserting events (which still fire for each item), so that a batch insert (e.g. extend/+=) can be handled with a single update. A single insert is just a length-1 range.
Note that the batch_* signals track structural changes only; slice assignment (el[a:b] = ...) may change the length of the list but emits only changed.
batch_removed class-attribute instance-attribute #
batch_removed = ListSignal(int, int, object)
(start, stop, values) emitted once after a contiguous block of items has been removed from the half-open range [start, stop) (values is the removed list, in list order, even though items are popped highest-index first).
batch_removing class-attribute instance-attribute #
batch_removing = ListSignal(int, int)
(start, stop) emitted once before a contiguous block of items is removed from the half-open range [start, stop).
Brackets the per-item removing events. Non-contiguous removals (e.g. a strided slice) emit this once per contiguous block, highest block first.
As with batch_inserting, slice assignment emits only changed.
changed class-attribute instance-attribute #
changed = ListSignal(object, object, object)
(index_or_slice, old_value, value) emitted when index is set from old_value to value
child_event class-attribute instance-attribute #
child_event = Signal(EmissionInfo)
(EmissionInfo) emitted when an object in the list emits an event. Note that the EventedList must be created with child_events=True in order for this to be emitted.
inserted class-attribute instance-attribute #
inserted = ListSignal(int, object)
(index, value) emitted after value is inserted at index
inserting class-attribute instance-attribute #
inserting = ListSignal(int)
(index) emitted before an item is inserted at index
moved class-attribute instance-attribute #
moved = ListSignal(int, int, object)
(index, new_index, value) emitted after value is moved from index to new_index
moving class-attribute instance-attribute #
moving = ListSignal(int, int)
(index, new_index) emitted before an item is moved from index to new_index
removed class-attribute instance-attribute #
removed = ListSignal(int, object)
(index, value) emitted after value is removed at index
removing class-attribute instance-attribute #
removing = ListSignal(int)
(index) emitted before an item is removed at index
reordered class-attribute instance-attribute #
reordered = Signal()
Emitted when the list is reordered (eg. moved/reversed).
OrderedSet #
OrderedSet(iterable: Iterable[_T] = ())
Bases: _BaseMutableSet[_T]
A set that preserves insertion order, uses dict behind the scenes.
Source code in src/psygnal/containers/_evented_set.py
216 217 218 | |
ProxyEvents #
ProxyEvents(instance: Any = None)
Bases: SignalGroup
Events emitted by EventedObjectProxy and EventedCallableObjectProxy.
Attributes:
-
attribute_deleted–Emitted when an attribute is deleted.
-
attribute_set–Emitted when an attribute is set.
-
in_place–Emitted when an in-place operation is performed.
-
item_deleted–Emitted when an item is deleted.
-
item_set–Emitted when an item is set.
Source code in src/psygnal/_group.py
429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 | |
attribute_deleted class-attribute instance-attribute #
attribute_deleted = Signal(str)
Emitted when an attribute is deleted.
attribute_set class-attribute instance-attribute #
attribute_set = Signal(str, object)
Emitted when an attribute is set.
in_place class-attribute instance-attribute #
in_place = Signal(str, object)
Emitted when an in-place operation is performed.
item_deleted class-attribute instance-attribute #
item_deleted = Signal(object)
Emitted when an item is deleted.
item_set class-attribute instance-attribute #
item_set = Signal(object, object)
Emitted when an item is set.
SelectableEventedList #
SelectableEventedList(
data: Iterable[_T] = (),
*,
hashable: bool = True,
child_events: bool = False,
)
Bases: Selectable[_T], EventedList[_T]
EventedList subclass with a built in selection model.
In addition to all EventedList properties, this class also has a selection attribute that manages a set of selected items in the list.
Parameters:
-
(data#iterable, default:()) –Elements to initialize the list with.
-
(hashable#bool, default:True) –Whether the list should be hashable as id(self). By default
True. -
(child_events#bool, default:False) –Whether to re-emit events from emitted from evented items in the list (i.e. items that have SignalInstances). If
True, child events can be connected atEventedList.events.child_event. By default,False.
Attributes:
-
events(ListEvents) –SignalGroup that with events related to list mutation. (see ListEvents)
-
selection(Selection) –An evented set containing the currently selected items, along with an
activeandcurrentitem. (SeeSelection)
Methods:
-
deselect_all–Deselect all items in the list.
-
insert–Insert item(s) into the list and update the selection.
-
remove_selected–Remove selected items from the list and the selection.
-
select_all–Select all items in the list.
-
select_next–Select the next item in the list.
-
select_previous–Select the previous item in the list.
Source code in src/psygnal/containers/_selectable_evented_list.py
40 41 42 43 44 45 46 47 48 49 | |
deselect_all #
deselect_all() -> None
Deselect all items in the list.
Source code in src/psygnal/containers/_selectable_evented_list.py
72 73 74 | |
insert #
insert(index: int, value: _T) -> None
Insert item(s) into the list and update the selection.
Parameters:
Source code in src/psygnal/containers/_selectable_evented_list.py
54 55 56 57 58 59 60 61 62 63 64 65 66 | |
remove_selected #
remove_selected() -> tuple[_T, ...]
Remove selected items from the list and the selection.
Returns:
-
Tuple[_T, ...]–The items that were removed.
Source code in src/psygnal/containers/_selectable_evented_list.py
128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 | |
select_all #
select_all() -> None
Select all items in the list.
Source code in src/psygnal/containers/_selectable_evented_list.py
68 69 70 | |
select_next #
select_next(
step: int = 1,
expand_selection: bool = False,
wraparound: bool = False,
) -> None
Select the next item in the list.
Parameters:
-
(step#int, default:1) –The step size to take when picking the next item, by default 1
-
(expand_selection#bool, default:False) –If True, will expand the selection to contain the both the current item and the next item, by default False
-
(wraparound#bool, default:False) –Whether to return to the beginning of the list of the end has been reached, by default False
Source code in src/psygnal/containers/_selectable_evented_list.py
76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 | |
select_previous #
select_previous(
expand_selection: bool = False, wraparound: bool = False
) -> None
Select the previous item in the list.
Parameters:
-
(expand_selection#bool, default:False) –If True, will expand the selection to contain both the current item and the previous item, by default False
-
(wraparound#bool, default:False) –Whether to return to the end of the list if the beginning has been reached, by default False
Source code in src/psygnal/containers/_selectable_evented_list.py
110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 | |
Selection #
Selection(
data: Iterable[_T] = (), parent: Container | None = None
)
Bases: EventedOrderedSet[_T]
An model of selected items, with a active and current item.
There can only be one active and one current item, but there can be multiple selected items. An "active" item is defined as a single selected item (if multiple items are selected, there is no active item). The "current" item is mostly useful for (e.g.) keyboard actions: even with multiple items selected, you may only have one current item, and keyboard events (like up and down) can modify that current item. It's possible to have a current item without an active item, but an active item will always be the current item.
An item can be the current item and selected at the same time. Qt views will ensure that there is always a current item as keyboard navigation, for example, requires a current item. This pattern mimics current/selected items from Qt: https://doc.qt.io/qt-5/model-view-programming.html#current-item-and-selected-items
Parameters:
-
(data#iterable, default:()) –Elements to initialize the set with.
-
(parent#Container, default:None) –The parent container, if any. This is used to provide validation upon mutation in common use cases.
Attributes:
-
events(SelectionEvents) –SignalGroup that with events related to selection changes. (see SelectionEvents)
-
active((Any, optional)) –The active item, if any. An "active" item is defined as a single selected item (if multiple items are selected, there is no active item)
-
_current((Any, optional)) –The current item, if any. This is used primarily by GUI views when handling mouse/key events.
Methods:
-
clear–Clear the selection.
-
replace_selection–Replace the current selection with
new_selection. -
select_only–Unselect everything but
obj. Add to selection if not currently selected. -
toggle–Toggle selection state of obj.
Source code in src/psygnal/containers/_selection.py
78 79 80 81 82 83 | |
clear #
clear(keep_current: bool = False) -> None
Clear the selection.
Parameters:
-
(keep_current#bool, default:False) –If
False(the default), the "current" item will also be set to None.
Source code in src/psygnal/containers/_selection.py
116 117 118 119 120 121 122 123 124 125 126 | |
replace_selection #
replace_selection(new_selection: Iterable[_T]) -> None
Replace the current selection with new_selection.
This is equivalent to calling intersection_update followed by update, but is more efficient because it only emits a single items_changed event.
Source code in src/psygnal/containers/_selection.py
138 139 140 141 142 143 144 145 146 | |
select_only #
select_only(obj: _T) -> None
Unselect everything but obj. Add to selection if not currently selected.
Source code in src/psygnal/containers/_selection.py
132 133 134 135 136 | |
toggle #
toggle(obj: _T) -> None
Toggle selection state of obj.
Source code in src/psygnal/containers/_selection.py
128 129 130 | |
SetEvents #
SetEvents(instance: Any = None)
Bases: SignalGroup
Events available on EventedSet.
Attributes:
-
items_changed (added(Tuple[Any, ...], removed: Tuple[Any, ...])) –A signal that will emitted whenever an item or items are added or removed. Connected callbacks will be called with
callback(added, removed), whereaddedandremovedare tuples containing the objects that have been added or removed from the set.
Source code in src/psygnal/_group.py
429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 | |