PyPDFForm 2.5.0__py3-none-any.whl → 3.0.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of PyPDFForm might be problematic. Click here for more details.
- PyPDFForm/__init__.py +22 -6
- PyPDFForm/adapter.py +28 -26
- PyPDFForm/constants.py +29 -34
- PyPDFForm/coordinate.py +23 -399
- PyPDFForm/filler.py +79 -303
- PyPDFForm/font.py +166 -164
- PyPDFForm/hooks.py +109 -69
- PyPDFForm/image.py +72 -22
- PyPDFForm/middleware/base.py +42 -60
- PyPDFForm/middleware/checkbox.py +27 -58
- PyPDFForm/middleware/dropdown.py +41 -30
- PyPDFForm/middleware/image.py +10 -22
- PyPDFForm/middleware/radio.py +30 -31
- PyPDFForm/middleware/signature.py +32 -47
- PyPDFForm/middleware/text.py +54 -48
- PyPDFForm/patterns.py +61 -106
- PyPDFForm/template.py +80 -427
- PyPDFForm/utils.py +142 -128
- PyPDFForm/watermark.py +77 -208
- PyPDFForm/widgets/base.py +57 -76
- PyPDFForm/widgets/checkbox.py +18 -21
- PyPDFForm/widgets/dropdown.py +18 -25
- PyPDFForm/widgets/image.py +11 -9
- PyPDFForm/widgets/radio.py +25 -35
- PyPDFForm/widgets/signature.py +29 -40
- PyPDFForm/widgets/text.py +18 -17
- PyPDFForm/wrapper.py +351 -443
- {pypdfform-2.5.0.dist-info → pypdfform-3.0.0.dist-info}/METADATA +6 -7
- pypdfform-3.0.0.dist-info/RECORD +35 -0
- {pypdfform-2.5.0.dist-info → pypdfform-3.0.0.dist-info}/WHEEL +1 -1
- pypdfform-2.5.0.dist-info/RECORD +0 -35
- {pypdfform-2.5.0.dist-info → pypdfform-3.0.0.dist-info}/licenses/LICENSE +0 -0
- {pypdfform-2.5.0.dist-info → pypdfform-3.0.0.dist-info}/top_level.txt +0 -0
PyPDFForm/hooks.py
CHANGED
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
# -*- coding: utf-8 -*-
|
|
2
|
-
"""
|
|
2
|
+
"""
|
|
3
|
+
This module defines widget hooks that allow for dynamic modification of PDF form fields.
|
|
3
4
|
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
5
|
+
It provides functions to trigger these hooks, enabling changes to text field properties
|
|
6
|
+
like font, font size, color, alignment, and multiline settings, as well as the size
|
|
7
|
+
of checkbox and radio button widgets. These hooks are triggered during the PDF form
|
|
8
|
+
filling process, allowing for customization of the form's appearance and behavior.
|
|
7
9
|
"""
|
|
8
10
|
|
|
9
11
|
import sys
|
|
@@ -15,7 +17,7 @@ from pypdf.generic import (ArrayObject, DictionaryObject, FloatObject,
|
|
|
15
17
|
NameObject, NumberObject, TextStringObject)
|
|
16
18
|
|
|
17
19
|
from .constants import (COMB, DA, FONT_COLOR_IDENTIFIER, FONT_SIZE_IDENTIFIER,
|
|
18
|
-
MULTILINE, Annots, Ff, Parent, Q, Rect)
|
|
20
|
+
MULTILINE, Annots, Ff, Opt, Parent, Q, Rect)
|
|
19
21
|
from .template import get_widget_key
|
|
20
22
|
from .utils import stream_to_io
|
|
21
23
|
|
|
@@ -25,21 +27,26 @@ def trigger_widget_hooks(
|
|
|
25
27
|
widgets: dict,
|
|
26
28
|
use_full_widget_name: bool,
|
|
27
29
|
) -> bytes:
|
|
28
|
-
"""
|
|
30
|
+
"""
|
|
31
|
+
Triggers widget hooks to apply dynamic changes to PDF form fields.
|
|
32
|
+
|
|
33
|
+
This function iterates through the annotations on each page of the PDF and,
|
|
34
|
+
if a widget is associated with an annotation and has hooks to trigger,
|
|
35
|
+
it executes those hooks. Hooks are functions defined in this module that
|
|
36
|
+
modify the annotation dictionary, allowing for dynamic changes to the form field's
|
|
37
|
+
appearance or behavior.
|
|
29
38
|
|
|
30
39
|
Args:
|
|
31
|
-
pdf: The
|
|
32
|
-
widgets:
|
|
33
|
-
|
|
40
|
+
pdf (bytes): The PDF file data as bytes.
|
|
41
|
+
widgets (dict): A dictionary of widgets, where keys are widget identifiers
|
|
42
|
+
and values are widget objects containing information about the widget
|
|
43
|
+
and its associated hooks.
|
|
44
|
+
use_full_widget_name (bool): Whether to use the full widget name when
|
|
45
|
+
looking up widgets in the widgets dictionary.
|
|
34
46
|
|
|
35
47
|
Returns:
|
|
36
|
-
The modified PDF
|
|
37
|
-
|
|
38
|
-
Note:
|
|
39
|
-
This function processes all pages and annotations in the PDF, applying
|
|
40
|
-
any hooks registered in the widget objects.
|
|
48
|
+
bytes: The modified PDF data as bytes, with the widget hooks applied.
|
|
41
49
|
"""
|
|
42
|
-
|
|
43
50
|
pdf_file = PdfReader(stream_to_io(pdf))
|
|
44
51
|
output = PdfWriter()
|
|
45
52
|
output.append(pdf_file)
|
|
@@ -65,18 +72,45 @@ def trigger_widget_hooks(
|
|
|
65
72
|
return f.read()
|
|
66
73
|
|
|
67
74
|
|
|
68
|
-
def
|
|
69
|
-
"""
|
|
75
|
+
def update_text_field_font(annot: DictionaryObject, val: str) -> None:
|
|
76
|
+
"""
|
|
77
|
+
Updates the font of a text field annotation.
|
|
78
|
+
|
|
79
|
+
This function modifies the appearance string (DA) in the annotation dictionary
|
|
80
|
+
to change the font used for the text field.
|
|
70
81
|
|
|
71
82
|
Args:
|
|
72
|
-
annot: The
|
|
73
|
-
val: The new font
|
|
83
|
+
annot (DictionaryObject): The annotation dictionary for the text field.
|
|
84
|
+
val (str): The new font name to use for the text field.
|
|
85
|
+
"""
|
|
86
|
+
if Parent in annot and DA not in annot:
|
|
87
|
+
text_appearance = annot[Parent][DA]
|
|
88
|
+
else:
|
|
89
|
+
text_appearance = annot[DA]
|
|
90
|
+
|
|
91
|
+
text_appearance = text_appearance.split(" ")
|
|
92
|
+
text_appearance[0] = val
|
|
93
|
+
new_text_appearance = " ".join(text_appearance)
|
|
94
|
+
|
|
95
|
+
if Parent in annot and DA not in annot:
|
|
96
|
+
annot[NameObject(Parent)][NameObject(DA)] = TextStringObject(
|
|
97
|
+
new_text_appearance
|
|
98
|
+
)
|
|
99
|
+
else:
|
|
100
|
+
annot[NameObject(DA)] = TextStringObject(new_text_appearance)
|
|
101
|
+
|
|
74
102
|
|
|
75
|
-
|
|
76
|
-
Handles both direct font size specification and inherited font sizes
|
|
77
|
-
from parent objects. Modifies the DA (default appearance) string.
|
|
103
|
+
def update_text_field_font_size(annot: DictionaryObject, val: float) -> None:
|
|
78
104
|
"""
|
|
105
|
+
Updates the font size of a text field annotation.
|
|
106
|
+
|
|
107
|
+
This function modifies the appearance string (DA) in the annotation dictionary
|
|
108
|
+
to change the font size used for the text field.
|
|
79
109
|
|
|
110
|
+
Args:
|
|
111
|
+
annot (DictionaryObject): The annotation dictionary for the text field.
|
|
112
|
+
val (float): The new font size to use for the text field.
|
|
113
|
+
"""
|
|
80
114
|
if Parent in annot and DA not in annot:
|
|
81
115
|
text_appearance = annot[Parent][DA]
|
|
82
116
|
else:
|
|
@@ -101,18 +135,16 @@ def update_text_field_font_size(annot: DictionaryObject, val: float) -> None:
|
|
|
101
135
|
|
|
102
136
|
|
|
103
137
|
def update_text_field_font_color(annot: DictionaryObject, val: tuple) -> None:
|
|
104
|
-
"""
|
|
138
|
+
"""
|
|
139
|
+
Updates the font color of a text field annotation.
|
|
105
140
|
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
val: Tuple containing RGB color values (e.g. (1, 0, 0) for red)
|
|
141
|
+
This function modifies the appearance string (DA) in the annotation dictionary
|
|
142
|
+
to change the font color used for the text field.
|
|
109
143
|
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
include the new color values after the font size identifier.
|
|
144
|
+
Args:
|
|
145
|
+
annot (DictionaryObject): The annotation dictionary for the text field.
|
|
146
|
+
val (tuple): The new font color as an RGB tuple (e.g., (1, 0, 0) for red).
|
|
114
147
|
"""
|
|
115
|
-
|
|
116
148
|
if Parent in annot and DA not in annot:
|
|
117
149
|
text_appearance = annot[Parent][DA]
|
|
118
150
|
else:
|
|
@@ -141,76 +173,84 @@ def update_text_field_font_color(annot: DictionaryObject, val: tuple) -> None:
|
|
|
141
173
|
|
|
142
174
|
|
|
143
175
|
def update_text_field_alignment(annot: DictionaryObject, val: int) -> None:
|
|
144
|
-
"""
|
|
176
|
+
"""
|
|
177
|
+
Updates the text alignment of a text field annotation.
|
|
145
178
|
|
|
146
|
-
|
|
147
|
-
|
|
179
|
+
This function modifies the Q entry in the annotation dictionary to change
|
|
180
|
+
the text alignment of the text field.
|
|
148
181
|
|
|
149
182
|
Args:
|
|
150
|
-
annot:
|
|
151
|
-
val:
|
|
183
|
+
annot (DictionaryObject): The annotation dictionary for the text field.
|
|
184
|
+
val (int): The new alignment value (0=Left, 1=Center, 2=Right).
|
|
152
185
|
"""
|
|
153
|
-
|
|
154
186
|
annot[NameObject(Q)] = NumberObject(val)
|
|
155
187
|
|
|
156
188
|
|
|
157
189
|
def update_text_field_multiline(annot: DictionaryObject, val: bool) -> None:
|
|
158
|
-
"""
|
|
190
|
+
"""
|
|
191
|
+
Updates the multiline property of a text field annotation.
|
|
159
192
|
|
|
160
|
-
|
|
161
|
-
|
|
193
|
+
This function modifies the Ff (flags) entry in the annotation dictionary to
|
|
194
|
+
enable or disable the multiline property of the text field.
|
|
162
195
|
|
|
163
196
|
Args:
|
|
164
|
-
annot:
|
|
165
|
-
val:
|
|
197
|
+
annot (DictionaryObject): The annotation dictionary for the text field.
|
|
198
|
+
val (bool): True to enable multiline, False to disable.
|
|
166
199
|
"""
|
|
167
|
-
|
|
168
200
|
if val:
|
|
169
201
|
annot[NameObject(Ff)] = NumberObject(int(annot[NameObject(Ff)]) | MULTILINE)
|
|
170
202
|
|
|
171
203
|
|
|
172
204
|
def update_text_field_comb(annot: DictionaryObject, val: bool) -> None:
|
|
173
|
-
"""
|
|
205
|
+
"""
|
|
206
|
+
Updates the comb property of a text field annotation.
|
|
174
207
|
|
|
175
|
-
|
|
176
|
-
|
|
208
|
+
This function modifies the Ff (flags) entry in the annotation dictionary to
|
|
209
|
+
enable or disable the comb property of the text field, which limits the
|
|
210
|
+
number of characters that can be entered in each line.
|
|
177
211
|
|
|
178
212
|
Args:
|
|
179
|
-
annot:
|
|
180
|
-
val:
|
|
213
|
+
annot (DictionaryObject): The annotation dictionary for the text field.
|
|
214
|
+
val (bool): True to enable comb, False to disable.
|
|
181
215
|
"""
|
|
182
|
-
|
|
183
216
|
if val:
|
|
184
217
|
annot[NameObject(Ff)] = NumberObject(int(annot[NameObject(Ff)]) | COMB)
|
|
185
218
|
|
|
186
219
|
|
|
187
220
|
def update_check_radio_size(annot: DictionaryObject, val: float) -> None:
|
|
188
|
-
"""
|
|
221
|
+
"""
|
|
222
|
+
Updates the size of a check box or radio button annotation.
|
|
189
223
|
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
val: New size value (width and height) for the widget
|
|
224
|
+
This function modifies the Rect entry in the annotation dictionary to change
|
|
225
|
+
the size of the check box or radio button.
|
|
193
226
|
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
227
|
+
Args:
|
|
228
|
+
annot (DictionaryObject): The annotation dictionary for the check box or
|
|
229
|
+
radio button.
|
|
230
|
+
val (float): The new size (width and height) for the check box or radio button.
|
|
197
231
|
"""
|
|
198
|
-
|
|
199
232
|
rect = annot[Rect]
|
|
200
|
-
|
|
201
|
-
center_y = (rect[1] + rect[3]) / 2
|
|
233
|
+
# scale from bottom left
|
|
202
234
|
new_rect = [
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
FloatObject(
|
|
206
|
-
FloatObject(
|
|
235
|
+
rect[0],
|
|
236
|
+
rect[1],
|
|
237
|
+
FloatObject(rect[0] + val),
|
|
238
|
+
FloatObject(rect[1] + val),
|
|
207
239
|
]
|
|
208
240
|
annot[NameObject(Rect)] = ArrayObject(new_rect)
|
|
209
241
|
|
|
210
242
|
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
243
|
+
def update_dropdown_choices(annot: DictionaryObject, val: list) -> None:
|
|
244
|
+
"""
|
|
245
|
+
Updates the choices in a dropdown field annotation.
|
|
246
|
+
|
|
247
|
+
This function modifies the Opt entry in the annotation dictionary to change
|
|
248
|
+
the available choices in the dropdown field.
|
|
249
|
+
|
|
250
|
+
Args:
|
|
251
|
+
annot (DictionaryObject): The annotation dictionary for the dropdown field.
|
|
252
|
+
val (list): A list of strings representing the new choices for the dropdown.
|
|
253
|
+
"""
|
|
254
|
+
annot[NameObject(Opt)] = ArrayObject(
|
|
255
|
+
[ArrayObject([TextStringObject(each), TextStringObject(each)]) for each in val]
|
|
256
|
+
)
|
PyPDFForm/image.py
CHANGED
|
@@ -1,12 +1,10 @@
|
|
|
1
1
|
# -*- coding: utf-8 -*-
|
|
2
|
-
"""
|
|
3
|
-
|
|
4
|
-
This module contains functions for:
|
|
5
|
-
- Rotating images while maintaining quality
|
|
6
|
-
- Extracting image dimensions
|
|
7
|
-
- Handling image streams and formats
|
|
2
|
+
"""
|
|
3
|
+
This module provides functionalities for handling images within PyPDFForm.
|
|
8
4
|
|
|
9
|
-
|
|
5
|
+
It includes functions for rotating images, retrieving image dimensions, and
|
|
6
|
+
calculating the resolutions for drawing an image on a PDF page, taking into
|
|
7
|
+
account whether to preserve the aspect ratio.
|
|
10
8
|
"""
|
|
11
9
|
|
|
12
10
|
from io import BytesIO
|
|
@@ -14,21 +12,26 @@ from typing import Tuple, Union
|
|
|
14
12
|
|
|
15
13
|
from PIL import Image
|
|
16
14
|
|
|
15
|
+
from .constants import Rect
|
|
16
|
+
|
|
17
17
|
|
|
18
18
|
def rotate_image(image_stream: bytes, rotation: Union[float, int]) -> bytes:
|
|
19
|
-
"""
|
|
19
|
+
"""
|
|
20
|
+
Rotates an image by a specified angle in degrees.
|
|
21
|
+
|
|
22
|
+
This function takes an image stream as bytes and rotates it using the PIL library.
|
|
23
|
+
The rotation is performed around the center of the image, and the expand=True
|
|
24
|
+
parameter ensures that the entire rotated image is visible, even if it extends
|
|
25
|
+
beyond the original image boundaries.
|
|
20
26
|
|
|
21
27
|
Args:
|
|
22
|
-
image_stream:
|
|
23
|
-
rotation:
|
|
28
|
+
image_stream (bytes): The image data as bytes.
|
|
29
|
+
rotation (Union[float, int]): The rotation angle in degrees. Positive values
|
|
30
|
+
rotate the image counterclockwise, while negative values rotate it clockwise.
|
|
24
31
|
|
|
25
32
|
Returns:
|
|
26
|
-
bytes:
|
|
27
|
-
|
|
28
|
-
Note:
|
|
29
|
-
Automatically expands the canvas to prevent cropping during rotation.
|
|
33
|
+
bytes: The rotated image data as bytes.
|
|
30
34
|
"""
|
|
31
|
-
|
|
32
35
|
buff = BytesIO()
|
|
33
36
|
buff.write(image_stream)
|
|
34
37
|
buff.seek(0)
|
|
@@ -48,18 +51,18 @@ def rotate_image(image_stream: bytes, rotation: Union[float, int]) -> bytes:
|
|
|
48
51
|
|
|
49
52
|
|
|
50
53
|
def get_image_dimensions(image_stream: bytes) -> Tuple[float, float]:
|
|
51
|
-
"""
|
|
54
|
+
"""
|
|
55
|
+
Retrieves the width and height of an image from its byte stream.
|
|
56
|
+
|
|
57
|
+
This function uses the PIL library to open the image from the provided byte stream
|
|
58
|
+
and returns its dimensions (width and height) as a tuple of floats.
|
|
52
59
|
|
|
53
60
|
Args:
|
|
54
|
-
image_stream:
|
|
61
|
+
image_stream (bytes): The image data as bytes.
|
|
55
62
|
|
|
56
63
|
Returns:
|
|
57
|
-
Tuple[float, float]:
|
|
58
|
-
|
|
59
|
-
Note:
|
|
60
|
-
Works with any image format supported by PIL (Pillow)
|
|
64
|
+
Tuple[float, float]: The width and height of the image in pixels.
|
|
61
65
|
"""
|
|
62
|
-
|
|
63
66
|
buff = BytesIO()
|
|
64
67
|
buff.write(image_stream)
|
|
65
68
|
buff.seek(0)
|
|
@@ -67,3 +70,50 @@ def get_image_dimensions(image_stream: bytes) -> Tuple[float, float]:
|
|
|
67
70
|
image = Image.open(buff)
|
|
68
71
|
|
|
69
72
|
return image.size
|
|
73
|
+
|
|
74
|
+
|
|
75
|
+
def get_draw_image_resolutions(
|
|
76
|
+
widget: dict,
|
|
77
|
+
preserve_aspect_ratio: bool,
|
|
78
|
+
image_width: float,
|
|
79
|
+
image_height: float,
|
|
80
|
+
) -> Tuple[float, float, float, float]:
|
|
81
|
+
"""
|
|
82
|
+
Calculates the position and dimensions for drawing an image on a PDF page.
|
|
83
|
+
|
|
84
|
+
This function determines the x, y coordinates, width, and height for drawing an
|
|
85
|
+
image within a specified widget area on a PDF page. It takes into account whether
|
|
86
|
+
the aspect ratio of the image should be preserved and adjusts the dimensions
|
|
87
|
+
accordingly.
|
|
88
|
+
|
|
89
|
+
Args:
|
|
90
|
+
widget (dict): A dictionary containing the widget's rectangle coordinates
|
|
91
|
+
(x1, y1, x2, y2) under the key "Rect".
|
|
92
|
+
preserve_aspect_ratio (bool): Whether to preserve the aspect ratio of the image.
|
|
93
|
+
If True, the image will be scaled to fit within the widget area while
|
|
94
|
+
maintaining its original aspect ratio.
|
|
95
|
+
image_width (float): The width of the image in pixels.
|
|
96
|
+
image_height (float): The height of the image in pixels.
|
|
97
|
+
|
|
98
|
+
Returns:
|
|
99
|
+
Tuple[float, float, float, float]: A tuple containing the x, y coordinates,
|
|
100
|
+
width, and height of the image to be drawn on the PDF page.
|
|
101
|
+
"""
|
|
102
|
+
x = float(widget[Rect][0])
|
|
103
|
+
y = float(widget[Rect][1])
|
|
104
|
+
width = abs(float(widget[Rect][0]) - float(widget[Rect][2]))
|
|
105
|
+
height = abs(float(widget[Rect][1]) - float(widget[Rect][3]))
|
|
106
|
+
|
|
107
|
+
if preserve_aspect_ratio:
|
|
108
|
+
ratio = max(image_width / width, image_height / height)
|
|
109
|
+
|
|
110
|
+
new_width = image_width / ratio
|
|
111
|
+
new_height = image_height / ratio
|
|
112
|
+
|
|
113
|
+
x += abs(new_width - width) / 2
|
|
114
|
+
y += abs(new_height - height) / 2
|
|
115
|
+
|
|
116
|
+
width = new_width
|
|
117
|
+
height = new_height
|
|
118
|
+
|
|
119
|
+
return x, y, width, height
|
PyPDFForm/middleware/base.py
CHANGED
|
@@ -1,29 +1,24 @@
|
|
|
1
1
|
# -*- coding: utf-8 -*-
|
|
2
|
-
"""
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
- Basic validation
|
|
2
|
+
"""
|
|
3
|
+
Module containing base classes for middleware.
|
|
4
|
+
|
|
5
|
+
This module defines the base class for form widgets, which are used to
|
|
6
|
+
represent form fields in a PDF document. The Widget class provides
|
|
7
|
+
common attributes and methods for all form widgets, such as name, value,
|
|
8
|
+
and schema definition.
|
|
10
9
|
"""
|
|
11
10
|
|
|
12
11
|
from typing import Any
|
|
13
12
|
|
|
14
13
|
|
|
15
14
|
class Widget:
|
|
16
|
-
"""
|
|
17
|
-
|
|
18
|
-
Provides common interface and functionality for:
|
|
19
|
-
- Managing widget names and values
|
|
20
|
-
- Handling visual properties (borders, colors)
|
|
21
|
-
- Generating JSON schema definitions
|
|
22
|
-
- Providing sample values
|
|
15
|
+
"""
|
|
16
|
+
Base class for form widget.
|
|
23
17
|
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
18
|
+
The Widget class provides a base implementation for form widgets,
|
|
19
|
+
which are used to represent form fields in a PDF document. It
|
|
20
|
+
defines common attributes and methods for all form widgets, such
|
|
21
|
+
as name, value, and schema definition.
|
|
27
22
|
"""
|
|
28
23
|
|
|
29
24
|
SET_ATTR_TRIGGER_HOOK_MAP = {}
|
|
@@ -33,87 +28,76 @@ class Widget:
|
|
|
33
28
|
name: str,
|
|
34
29
|
value: Any = None,
|
|
35
30
|
) -> None:
|
|
36
|
-
"""
|
|
31
|
+
"""
|
|
32
|
+
Initialize a new widget.
|
|
37
33
|
|
|
38
34
|
Args:
|
|
39
|
-
name:
|
|
40
|
-
value:
|
|
35
|
+
name (str): The name of the widget.
|
|
36
|
+
value (Any): The initial value of the widget. Defaults to None.
|
|
41
37
|
"""
|
|
42
|
-
|
|
43
38
|
super().__init__()
|
|
44
39
|
self._name = name
|
|
45
40
|
self._value = value
|
|
46
41
|
self.desc = None
|
|
47
|
-
self.border_color = None
|
|
48
|
-
self.background_color = None
|
|
49
|
-
self.border_width = None
|
|
50
|
-
self.border_style = None
|
|
51
|
-
self.dash_array = None
|
|
52
|
-
self.render_widget = None
|
|
53
42
|
self.hooks_to_trigger = []
|
|
54
43
|
|
|
55
44
|
def __setattr__(self, name: str, value: Any) -> None:
|
|
56
|
-
"""
|
|
45
|
+
"""
|
|
46
|
+
Set an attribute on the widget.
|
|
57
47
|
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
All other attributes are set normally via the standard object.__setattr__.
|
|
48
|
+
This method overrides the default __setattr__ method to
|
|
49
|
+
trigger hooks when certain attributes are set.
|
|
61
50
|
|
|
62
51
|
Args:
|
|
63
|
-
name:
|
|
64
|
-
value:
|
|
65
|
-
|
|
66
|
-
Note:
|
|
67
|
-
The hook triggering only occurs when:
|
|
68
|
-
1. The attribute is in SET_ATTR_TRIGGER_HOOK_MAP
|
|
69
|
-
2. The value being set is not None
|
|
52
|
+
name (str): The name of the attribute.
|
|
53
|
+
value (Any): The value of the attribute.
|
|
70
54
|
"""
|
|
71
|
-
|
|
72
55
|
if name in self.SET_ATTR_TRIGGER_HOOK_MAP and value is not None:
|
|
73
56
|
self.hooks_to_trigger.append((self.SET_ATTR_TRIGGER_HOOK_MAP[name], value))
|
|
74
57
|
super().__setattr__(name, value)
|
|
75
58
|
|
|
76
59
|
@property
|
|
77
60
|
def name(self) -> str:
|
|
78
|
-
"""
|
|
61
|
+
"""
|
|
62
|
+
Get the name of the widget.
|
|
79
63
|
|
|
80
64
|
Returns:
|
|
81
|
-
str: The
|
|
65
|
+
str: The name of the widget.
|
|
82
66
|
"""
|
|
83
|
-
|
|
84
67
|
return self._name
|
|
85
68
|
|
|
86
69
|
@property
|
|
87
70
|
def value(self) -> Any:
|
|
88
|
-
"""
|
|
71
|
+
"""
|
|
72
|
+
Get the value of the widget.
|
|
89
73
|
|
|
90
74
|
Returns:
|
|
91
|
-
Any: The
|
|
75
|
+
Any: The value of the widget.
|
|
92
76
|
"""
|
|
93
|
-
|
|
94
77
|
return self._value
|
|
95
78
|
|
|
96
79
|
@value.setter
|
|
97
80
|
def value(self, value: Any) -> None:
|
|
98
|
-
"""
|
|
81
|
+
"""
|
|
82
|
+
Set the value of the widget.
|
|
99
83
|
|
|
100
84
|
Args:
|
|
101
|
-
value:
|
|
85
|
+
value (Any): The value to set.
|
|
102
86
|
"""
|
|
103
|
-
|
|
104
87
|
self._value = value
|
|
105
88
|
|
|
106
89
|
@property
|
|
107
90
|
def schema_definition(self) -> dict:
|
|
108
|
-
"""
|
|
91
|
+
"""
|
|
92
|
+
Get the schema definition of the widget.
|
|
93
|
+
|
|
94
|
+
This method returns a dictionary that defines the schema
|
|
95
|
+
for the widget. The schema definition is used to validate
|
|
96
|
+
the widget's value.
|
|
109
97
|
|
|
110
98
|
Returns:
|
|
111
|
-
dict:
|
|
112
|
-
- description (if available)
|
|
113
|
-
- type constraints
|
|
114
|
-
- other widget-specific properties
|
|
99
|
+
dict: The schema definition of the widget.
|
|
115
100
|
"""
|
|
116
|
-
|
|
117
101
|
result = {}
|
|
118
102
|
|
|
119
103
|
if self.desc is not None:
|
|
@@ -123,12 +107,10 @@ class Widget:
|
|
|
123
107
|
|
|
124
108
|
@property
|
|
125
109
|
def sample_value(self) -> Any:
|
|
126
|
-
"""
|
|
127
|
-
|
|
128
|
-
Returns:
|
|
129
|
-
Any: A representative value demonstrating the widget's expected input
|
|
110
|
+
"""
|
|
111
|
+
Get a sample value for the widget.
|
|
130
112
|
|
|
131
113
|
Raises:
|
|
132
|
-
NotImplementedError:
|
|
114
|
+
NotImplementedError: This method must be implemented by subclasses.
|
|
133
115
|
"""
|
|
134
116
|
raise NotImplementedError
|