Skip to content

Commit 7592095

Browse files
Document requirements for listener disconnection (#4102)
Co-authored-by: Russell Keith-Magee <russell@keith-magee.com>
1 parent 4225b5c commit 7592095

File tree

2 files changed

+27
-1
lines changed

2 files changed

+27
-1
lines changed

changes/4030.doc.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Data source topic guide now includes a discussion of how and when to connect and disconnect Listeners from Sources.

docs/en/topics/data-sources.md

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,32 @@ If any attribute of a [`ValueSource`][toga.sources.ValueSource], [`Row`][toga.so
3131

3232
When you create a widget like Selection or Table, and provide a data source for that widget, the widget is automatically added as a listener on that source.
3333

34-
Although widgets are the obvious listeners for a data source, *any* object can register as a listener. For example, a second data source might register as a listener to an initial source to implement a filtered source. When an item is added to the first data source, the second data source will be notified, and can choose whether to include the new item in its own data representation. Listeners only have to implement the methods that they need for their functionality: missing methods will be ignored.
34+
Although widgets are the obvious listeners for a data source, *any* object can register as a listener. For example, a second data source might register as a listener to an initial source to implement a filtered source. When an item is added to the first data source, the second data source will be notified, and can choose whether to include the new item in its own data representation. Listeners only have to implement the methods that they need for their functionality. Missing methods will be ignored.
35+
36+
You can add a listener by calling the [`add_listener`][toga.sources.base.Source.add_listener] method with your listener object. The standard data sources based off of the [`Source`][toga.sources.base.Source] class hold references to all their listeners and will continue to notify the listener as long as the data source remains in memory. When a listener is finished listening to a data source, you should call [`remove_listener`][toga.sources.base.Source.remove_listener] to remove the listener from the source.
37+
38+
This is particularly important if you might change the source that the listener is listening to. When you change data source you should make sure that you remove from the old one and connect to the new one:
39+
40+
``` python
41+
class DataSourceListener:
42+
...
43+
@property
44+
def data(self):
45+
return self._data
46+
47+
@data.setter
48+
def data(self, data):
49+
# disconnect as a listener on the old data source
50+
self._data.remove_listener(self)
51+
# store a reference to the new data source
52+
self._data = data
53+
# register as a listener on the new data source
54+
self._data.add_listener(self)
55+
```
56+
57+
If you don't disconnect, then your listener will get notifications from *both* data sources.
58+
59+
Often the lifetimes of data sources are closely tied to the listeners and widgets which use them, but sometimes — particularly for custom data sources — the data source may live for a long time. In these cases you should make sure that you disconnect widgets and listeners from the data source when you no longer need them. To disconnect a widget from a source, set its [`data`][toga.widgets.table.Table.data] property to `None` (or its [`items`][toga.widgets.selection.Selection.items] to `None` for a [`Selection`][toga.widgets.selection.Selection] widget). For other listeners, call [`remove_listener`][toga.sources.base.Source.remove_listener] directly. This will improve performance, and prevent delays in garbage collection of objects that your application is no longer using.
3560

3661
## Custom data sources
3762

0 commit comments

Comments
 (0)