@@ -116,131 +116,138 @@ with the new value as the first argument.
116116
117117There are two (related) APIs for adding events to dataclasses:
118118
119- 1 . Add a [ ` SignalGroupDescriptor ` ] [ psygnal.SignalGroupDescriptor ] as a class attribute.
119+ ### 1. Use ` SignalGroupDescriptor `
120120
121- !!! example
121+ [ ` SignalGroupDescriptor ` ] [ psygnal.SignalGroupDescriptor ] is designed to be used
122+ as a class attribute on a dataclass-like object, and, when accessed on an
123+ instance of that class, will return a [ ` SignalGroup ` ] [ psygnal.SignalGroup ] with
124+ signals for each field in the class.
122125
123- === "dataclasses"
126+ !!! example
124127
125- ```python
126- from typing import ClassVar
127- from psygnal import SignalGroupDescriptor
128- from dataclasses import dataclass
128+ === "dataclasses"
129129
130- @dataclass
131- class Person:
132- name: str
133- age: int = 0
134- events: ClassVar[SignalGroupDescriptor] = SignalGroupDescriptor()
135- ```
130+ ```python
131+ from typing import ClassVar
132+ from psygnal import SignalGroupDescriptor
133+ from dataclasses import dataclass
136134
137- === "pydantic"
135+ @dataclass
136+ class Person:
137+ name: str
138+ age: int = 0
139+ events: ClassVar[SignalGroupDescriptor] = SignalGroupDescriptor()
140+ ```
138141
139- ```python
140- from typing import ClassVar
141- from psygnal import SignalGroupDescriptor
142- from pydantic import BaseModel
142+ === "pydantic"
143143
144- class Person(BaseModel):
145- name: str
146- age: int = 0
147- events: ClassVar[SignalGroupDescriptor] = SignalGroupDescriptor()
148- ```
144+ ```python
145+ from typing import ClassVar
146+ from psygnal import SignalGroupDescriptor
147+ from pydantic import BaseModel
149148
150- *for a fully evented subclass of pydantic's `BaseModel`, see also
151- [`EventedModel`](./API/model.md)*
149+ class Person(BaseModel):
150+ name: str
151+ age: int = 0
152+ events: ClassVar[SignalGroupDescriptor] = SignalGroupDescriptor()
153+ ```
152154
153- === "msgspec"
155+ *for a fully evented subclass of pydantic's `BaseModel`, see also
156+ [`EventedModel`](./model.md)*
154157
155- ```python
156- from typing import ClassVar
157- from psygnal import SignalGroupDescriptor
158- import msgspec
158+ === "msgspec"
159159
160- class Person(msgspec.Struct):
161- name: str
162- age: int = 0
163- events: ClassVar[SignalGroupDescriptor] = SignalGroupDescriptor()
164- ```
160+ ```python
161+ from typing import ClassVar
162+ from psygnal import SignalGroupDescriptor
163+ import msgspec
165164
166- === "attrs"
165+ class Person(msgspec.Struct):
166+ name: str
167+ age: int = 0
168+ events: ClassVar[SignalGroupDescriptor] = SignalGroupDescriptor()
169+ ```
167170
168- ```python
169- from typing import ClassVar
170- from psygnal import SignalGroupDescriptor
171- from attrs import define
171+ === "attrs"
172172
173- @define
174- class Person:
175- name: str
176- age: int = 0
177- events: ClassVar[SignalGroupDescriptor] = SignalGroupDescriptor()
178- ```
173+ ```python
174+ from typing import ClassVar
175+ from psygnal import SignalGroupDescriptor
176+ from attrs import define
179177
180- 2 . Decorate the class with the [ ` @evented ` decorator] [ psygnal.evented ] .
178+ @define
179+ class Person:
180+ name: str
181+ age: int = 0
182+ events: ClassVar[SignalGroupDescriptor] = SignalGroupDescriptor()
183+ ```
181184
182- > _ Under the hood, this just adds the ` SignalGroupDescriptor ` as a class
183- > attribute named "events" for you, as shown above). Prefer the class
184- > attribute pattern to the decorator when in doubt._
185+ ### 2. Use the ` @evented ` decorator
185186
186- !!! example
187+ The [ ` @evented ` ] [ psygnal.evented ] decorator can be added to any dataclass-like
188+ class. Under the hood, this just adds the ` SignalGroupDescriptor ` as a class
189+ attribute for you (named "events" by default), as shown above. Prefer the class
190+ attribute pattern to the decorator when in doubt, as it is more explicit and
191+ leads to better type checking.
187192
188- === "dataclasses"
193+ !!! example
189194
190- ```python
191- from psygnal import evented
192- from dataclasses import dataclass
195+ === "dataclasses"
193196
194- @evented
195- @dataclass
196- class Person:
197- name: str
198- age: int = 0
199- ```
197+ ```python
198+ from psygnal import evented
199+ from dataclasses import dataclass
200200
201- === "pydantic"
201+ @evented
202+ @dataclass
203+ class Person:
204+ name: str
205+ age: int = 0
206+ ```
202207
203- ```python
204- from psygnal import evented
205- from pydantic import BaseModel
208+ === "pydantic"
206209
207- @evented
208- class Person(BaseModel):
209- name: str
210- age: int = 0
211- ```
210+ ```python
211+ from psygnal import evented
212+ from pydantic import BaseModel
212213
213- *for a fully evented subclass of pydantic's `BaseModel`, see also
214- [`EventedModel`](./API/model.md)*
214+ @evented
215+ class Person(BaseModel):
216+ name: str
217+ age: int = 0
218+ ```
215219
216- === "msgspec"
220+ *for a fully evented subclass of pydantic's `BaseModel`, see also
221+ [`EventedModel`](./model.md)*
217222
218- ```python
219- from psygnal import evented
220- import msgspec
223+ === "msgspec"
221224
222- @evented
223- class Person(msgspec.Struct):
224- name: str
225- age: int = 0
226- ```
225+ ```python
226+ from psygnal import evented
227+ import msgspec
228+
229+ @evented
230+ class Person(msgspec.Struct):
231+ name: str
232+ age: int = 0
233+ ```
227234
228- === "attrs"
235+ === "attrs"
236+
237+ ```python
238+ from psygnal import evented
239+ from attrs import define
229240
230- ```python
231- from psygnal import evented
232- from attrs import define
241+ @evented
242+ @define
243+ class Person:
244+ name: str
245+ age: int = 0
246+ ```
233247
234- @evented
235- @define
236- class Person:
237- name: str
238- age: int = 0
239- ```
240-
241- !!! tip
242- by default, the ` SignalGroup ` instance is named ` 'events' ` , but this can be
243- changed by passing a ` events_namespace ` argument to the ` @evented ` decorator)
248+ !!! tip
249+ by default, the ` SignalGroup ` instance is named ` 'events' ` , but this can be
250+ changed by passing a ` events_namespace ` argument to the ` @evented ` decorator)
244251
245252Using any of the above, you can now connect callbacks to the change events
246253of any field on the object (there will be a signal instance in the ` events `
@@ -270,7 +277,7 @@ def on_any_change(info: EmissionInfo):
270277 print (f " field { info.signal.name!r } changed to { info.args} " )
271278```
272279
273- see the [ API documentation] ( ./API/evented.md ) for for more details.
280+ see the [ API documentation] ( reference/psygnal/ ) for for more details.
274281
275282## Type annotating evented dataclasses
276283
0 commit comments