dearpygui-forms 0.2.0__py3-none-any.whl → 0.3.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.
- dearpygui_forms/dpg_form.py +4 -0
- dearpygui_forms/exceptions.py +2 -0
- dearpygui_forms/models.py +1 -0
- dearpygui_forms/widgets.py +127 -39
- {dearpygui_forms-0.2.0.dist-info → dearpygui_forms-0.3.0.dist-info}/METADATA +5 -1
- dearpygui_forms-0.3.0.dist-info/RECORD +8 -0
- dearpygui_forms-0.2.0.dist-info/RECORD +0 -7
- {dearpygui_forms-0.2.0.dist-info → dearpygui_forms-0.3.0.dist-info}/WHEEL +0 -0
dearpygui_forms/dpg_form.py
CHANGED
@@ -9,6 +9,7 @@ from loguru import logger
|
|
9
9
|
|
10
10
|
from .models import PropertySchema
|
11
11
|
from .widgets import *
|
12
|
+
from . import exceptions
|
12
13
|
|
13
14
|
|
14
15
|
def extract_defs(schema: dict[str, Any]) -> tuple[dict[str, Any], dict[str, Any]]:
|
@@ -46,6 +47,9 @@ class DPGForm:
|
|
46
47
|
except pydantic.ValidationError as e:
|
47
48
|
with dpg.window(modal=True, label="Validation Error"):
|
48
49
|
dpg.add_text(f"Validation error: {e}")
|
50
|
+
except exceptions.DearpyguiFormsError as e:
|
51
|
+
with dpg.window(modal=True, label="Form Error"):
|
52
|
+
dpg.add_text(f"Form error: {e}")
|
49
53
|
else:
|
50
54
|
self._callback(data)
|
51
55
|
|
dearpygui_forms/models.py
CHANGED
@@ -9,6 +9,7 @@ class PropertySchema:
|
|
9
9
|
self.anyOf: list[dict[str, Any]] = schema.get("anyOf", [])
|
10
10
|
self.properties: dict[str, dict[str, Any]] = schema.get("properties", {})
|
11
11
|
self.default = schema.get("default", None)
|
12
|
+
self.items = schema.get("items", None)
|
12
13
|
|
13
14
|
def __repr__(self) -> str:
|
14
15
|
return f"PropertySchema(title={self.title}, type={self.type}, anyOf={self.anyOf}, properties={self.properties}, default={self.default})"
|
dearpygui_forms/widgets.py
CHANGED
@@ -6,6 +6,7 @@ from loguru import logger
|
|
6
6
|
|
7
7
|
|
8
8
|
from .models import PropertySchema
|
9
|
+
from .exceptions import DearpyguiFormsError
|
9
10
|
|
10
11
|
|
11
12
|
@logger.catch
|
@@ -26,7 +27,8 @@ class Widget:
|
|
26
27
|
self._defs = defs
|
27
28
|
self._kwargs = kwargs
|
28
29
|
with dpg.stage() as self._staging_container_id:
|
29
|
-
|
30
|
+
with dpg.group() as self._root_item:
|
31
|
+
self._ui()
|
30
32
|
|
31
33
|
if schema.default:
|
32
34
|
self.set_value(schema.default)
|
@@ -34,8 +36,25 @@ class Widget:
|
|
34
36
|
def _ui(self):
|
35
37
|
dpg.add_text(f"Property {self.schema.title}, type: {self.schema.type}")
|
36
38
|
|
37
|
-
def add(self):
|
38
|
-
|
39
|
+
def add(self, parent=None, hidden=False):
|
40
|
+
"""
|
41
|
+
Add widget as dpg ui item.
|
42
|
+
"""
|
43
|
+
if parent is not None:
|
44
|
+
dpg.push_container_stack(parent)
|
45
|
+
dpg.unstage(self._staging_container_id)
|
46
|
+
dpg.pop_container_stack()
|
47
|
+
else:
|
48
|
+
dpg.unstage(self._staging_container_id)
|
49
|
+
|
50
|
+
if hidden:
|
51
|
+
self.hide()
|
52
|
+
|
53
|
+
def hide(self):
|
54
|
+
dpg.hide_item(self._root_item)
|
55
|
+
|
56
|
+
def show(self):
|
57
|
+
dpg.show_item(self._root_item)
|
39
58
|
|
40
59
|
def set_value(self, value: Any):
|
41
60
|
pass
|
@@ -43,17 +62,20 @@ class Widget:
|
|
43
62
|
def get_value(self) -> Any:
|
44
63
|
pass
|
45
64
|
|
65
|
+
def __del__(self):
|
66
|
+
dpg.delete_item(self._root_item)
|
46
67
|
|
47
68
|
|
48
69
|
class ObjectWidget(Widget):
|
49
70
|
def __init__(self, schema, defs, **kwargs):
|
50
|
-
self._properties = {}
|
71
|
+
self._properties: dict[str, Widget] = {}
|
51
72
|
super().__init__(schema, defs, **kwargs)
|
52
73
|
|
53
74
|
def _ui(self):
|
54
75
|
for property_name, property in self.schema.properties.items():
|
55
76
|
property_widget = generate_widget(property, self._defs, generate_object=False)
|
56
77
|
property_widget.add()
|
78
|
+
dpg.add_spacer(height=10)
|
57
79
|
self._properties[property_name] = property_widget
|
58
80
|
|
59
81
|
def get_value(self) -> dict[str, Any]:
|
@@ -64,38 +86,112 @@ class ObjectWidget(Widget):
|
|
64
86
|
property_widget.set_value(value.get(property_name))
|
65
87
|
|
66
88
|
|
89
|
+
class ExternalWidget(Widget):
|
90
|
+
def __init__(self, schema, defs, **kwargs):
|
91
|
+
self._external_id = dpg.generate_uuid()
|
92
|
+
self._widget: Widget | None = None
|
93
|
+
super().__init__(schema, defs, **kwargs)
|
94
|
+
|
95
|
+
def _ui(self):
|
96
|
+
if self.schema.title:
|
97
|
+
dpg.add_text(self.schema.title)
|
98
|
+
with dpg.group(indent=25) as self._form:
|
99
|
+
self._edit_button = dpg.add_button(label=f"Edit", callback=self.show_object_form)
|
100
|
+
|
101
|
+
def show_object_form(self):
|
102
|
+
if self._widget is None:
|
103
|
+
dpg.delete_item(self._edit_button)
|
104
|
+
self._widget = ObjectWidget(self.schema, self._defs)
|
105
|
+
self._widget.add(parent=self._form)
|
106
|
+
|
107
|
+
def get_value(self):
|
108
|
+
if self._widget is None:
|
109
|
+
raise DearpyguiFormsError(f"{self.schema.title}: set up object.")
|
110
|
+
return self._widget.get_value()
|
111
|
+
|
112
|
+
def set_value(self, value):
|
113
|
+
self.show_object_form()
|
114
|
+
self._widget.set_value(value)
|
115
|
+
|
116
|
+
|
117
|
+
|
67
118
|
class ArrayWidget(Widget):
|
68
119
|
def __init__(self, schema, defs, **kwargs):
|
69
120
|
super().__init__(schema, defs, **kwargs)
|
121
|
+
self.widgets: list[Widget] = []
|
122
|
+
|
123
|
+
def _ui(self):
|
124
|
+
with dpg.group(horizontal=True):
|
125
|
+
dpg.add_text(f"{self.schema.title}")
|
126
|
+
dpg.add_button(label="Add", callback=self.add_item)
|
127
|
+
dpg.add_button(label="Remove", callback=self.remove_item)
|
128
|
+
with dpg.group(indent=25) as self._form:
|
129
|
+
pass
|
130
|
+
|
131
|
+
def add_item(self):
|
132
|
+
widget = generate_widget(self.schema.items, self._defs)
|
133
|
+
self.widgets.append(widget)
|
134
|
+
widget.add(parent=self._form)
|
135
|
+
|
136
|
+
def remove_item(self):
|
137
|
+
if self.widgets:
|
138
|
+
widget = self.widgets.pop()
|
139
|
+
dpg.delete_item(widget._root_item)
|
140
|
+
|
141
|
+
def get_value(self):
|
142
|
+
return [widget.get_value() for widget in self.widgets]
|
143
|
+
|
144
|
+
def set_value(self, value):
|
145
|
+
self.widgets = []
|
146
|
+
for item in value:
|
147
|
+
widget = generate_widget(self.schema.items, self._defs)
|
148
|
+
self.widgets.append(widget)
|
149
|
+
widget.set_value(item)
|
150
|
+
widget.add(parent=self._form)
|
151
|
+
|
70
152
|
|
71
153
|
|
72
154
|
class MultiTypeWidget(Widget):
|
73
155
|
def __init__(self, schema, defs, **kwargs):
|
74
156
|
self._type_switcher_id = dpg.generate_uuid()
|
75
157
|
self._widget: Widget | None = None
|
76
|
-
self._widgets
|
77
|
-
|
78
|
-
|
158
|
+
self._widgets: dict[str, Widget] = {}
|
159
|
+
for type_schema in schema.anyOf:
|
160
|
+
widget = generate_widget(type_schema, defs, generate_object=False)
|
161
|
+
self._widgets[widget.schema.title or widget.schema.type] = widget
|
79
162
|
|
163
|
+
super().__init__(schema, defs, **kwargs)
|
80
164
|
|
81
165
|
def _ui(self):
|
82
|
-
dpg.
|
83
|
-
|
84
|
-
|
85
|
-
|
166
|
+
with dpg.group(horizontal=True):
|
167
|
+
if self.schema.title:
|
168
|
+
dpg.add_text(self.schema.title)
|
169
|
+
items = list(self._widgets.keys())
|
170
|
+
for i in items:
|
171
|
+
dpg.add_button(label=i,
|
172
|
+
user_data=i,
|
173
|
+
callback=lambda sender, app_data, user_data: self.switch_value_type(user_data),
|
174
|
+
small=True
|
175
|
+
)
|
176
|
+
with dpg.group() as self._form:
|
177
|
+
for widget in self._widgets.values():
|
178
|
+
widget.add(hidden=True)
|
86
179
|
|
87
180
|
def switch_value_type(self, new_type):
|
88
|
-
|
89
|
-
|
181
|
+
if self._widget is not None:
|
182
|
+
self._widget.hide()
|
183
|
+
self._widget = self._widgets[new_type]
|
184
|
+
self._widget.show()
|
90
185
|
|
91
186
|
def get_value(self):
|
92
187
|
if self._widget:
|
93
188
|
return self._widget.get_value()
|
94
189
|
else:
|
95
|
-
|
190
|
+
raise DearpyguiFormsError(f"{self.schema.title}: choose value type")
|
96
191
|
|
97
192
|
def set_value(self, value):
|
98
|
-
|
193
|
+
pass
|
194
|
+
# dpg.set_value(self._type_switcher_id, value)
|
99
195
|
|
100
196
|
|
101
197
|
class StringWidget(Widget):
|
@@ -104,7 +200,9 @@ class StringWidget(Widget):
|
|
104
200
|
super().__init__(schema, defs, **kwargs)
|
105
201
|
|
106
202
|
def _ui(self):
|
107
|
-
|
203
|
+
if self.schema.title:
|
204
|
+
dpg.add_text(self.schema.title)
|
205
|
+
dpg.add_input_text(tag=self._input_id)
|
108
206
|
|
109
207
|
def get_value(self):
|
110
208
|
return dpg.get_value(self._input_id)
|
@@ -119,7 +217,9 @@ class IntegerWidget(Widget):
|
|
119
217
|
super().__init__(schema, defs, **kwargs)
|
120
218
|
|
121
219
|
def _ui(self):
|
122
|
-
|
220
|
+
if self.schema.title:
|
221
|
+
dpg.add_text(self.schema.title)
|
222
|
+
dpg.add_input_int(tag=self._input_id)
|
123
223
|
|
124
224
|
def get_value(self):
|
125
225
|
return dpg.get_value(self._input_id)
|
@@ -134,7 +234,9 @@ class NumberWidget(Widget):
|
|
134
234
|
super().__init__(schema, defs, **kwargs)
|
135
235
|
|
136
236
|
def _ui(self):
|
137
|
-
|
237
|
+
if self.schema.title:
|
238
|
+
dpg.add_text(self.schema.title)
|
239
|
+
dpg.add_input_float(tag=self._input_id)
|
138
240
|
|
139
241
|
def get_value(self):
|
140
242
|
return dpg.get_value(self._input_id)
|
@@ -149,7 +251,9 @@ class BooleanWidget(Widget):
|
|
149
251
|
super().__init__(schema, defs, **kwargs)
|
150
252
|
|
151
253
|
def _ui(self):
|
152
|
-
|
254
|
+
if self.schema.title:
|
255
|
+
dpg.add_text(self.schema.title)
|
256
|
+
dpg.add_checkbox(tag=self._checkbox_id)
|
153
257
|
|
154
258
|
def get_value(self):
|
155
259
|
return dpg.get_value(self._checkbox_id)
|
@@ -163,22 +267,9 @@ class NoneWidget(Widget):
|
|
163
267
|
super().__init__(schema, defs, **kwargs)
|
164
268
|
|
165
269
|
def _ui(self):
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
return None
|
170
|
-
|
171
|
-
def set_value(self, value):
|
172
|
-
pass
|
173
|
-
|
174
|
-
|
175
|
-
class ExternalWidget(Widget):
|
176
|
-
def __init__(self, schema, defs, **kwargs):
|
177
|
-
self._external_id = dpg.generate_uuid()
|
178
|
-
super().__init__(schema, defs, **kwargs)
|
179
|
-
|
180
|
-
def _ui(self):
|
181
|
-
dpg.add_button(label=self.schema.title, tag=self._external_id, enabled=False)
|
270
|
+
if self.schema.title:
|
271
|
+
dpg.add_text(self.schema.title)
|
272
|
+
dpg.add_text("<None>", color=(128, 128, 128))
|
182
273
|
|
183
274
|
def get_value(self):
|
184
275
|
return None
|
@@ -194,10 +285,8 @@ def generate_widget(json_schema: dict[str, Any], defs: dict[str, Any], generate
|
|
194
285
|
if generate_object:
|
195
286
|
return ObjectWidget(schema, defs, **kwargs)
|
196
287
|
else:
|
197
|
-
raise NotImplementedError("ExternalWidget is not implemented yet")
|
198
288
|
return ExternalWidget(schema, defs, **kwargs)
|
199
289
|
case PropertySchema(type='array'):
|
200
|
-
raise NotImplementedError("ArrayWidget is not implemented yet")
|
201
290
|
return ArrayWidget(schema, defs, **kwargs)
|
202
291
|
case PropertySchema(type='string'):
|
203
292
|
return StringWidget(schema, defs, **kwargs)
|
@@ -210,7 +299,6 @@ def generate_widget(json_schema: dict[str, Any], defs: dict[str, Any], generate
|
|
210
299
|
case PropertySchema(type='null'):
|
211
300
|
return NoneWidget(schema, defs, **kwargs)
|
212
301
|
case PropertySchema(anyOf=types) if len(types) > 0:
|
213
|
-
|
214
|
-
# return MultiTypeWidget(schema, defs, **kwargs)
|
302
|
+
return MultiTypeWidget(schema, defs, **kwargs)
|
215
303
|
case _:
|
216
304
|
raise ValueError(f"Unsupported schema: {schema}")
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.4
|
2
2
|
Name: dearpygui-forms
|
3
|
-
Version: 0.
|
3
|
+
Version: 0.3.0
|
4
4
|
Summary: Dearpygui extention for autogeneration forms powered by pydantic.
|
5
5
|
Project-URL: homepage, https://github.com/vlewicki/dearpygui-forms
|
6
6
|
Author-email: Valentin Lewicki <vlewicki@vlewicki.ru>
|
@@ -21,6 +21,8 @@ Generate GUI forms for your Pydantic models.
|
|
21
21
|
|
22
22
|
|
23
23
|
Currently supported Pydantic fields:
|
24
|
+
- nested entities
|
25
|
+
- arrays
|
24
26
|
- str
|
25
27
|
- int
|
26
28
|
- float
|
@@ -28,6 +30,8 @@ Currently supported Pydantic fields:
|
|
28
30
|
- datetime
|
29
31
|
- date
|
30
32
|
- time
|
33
|
+
- anyOf sequences
|
34
|
+
|
31
35
|
|
32
36
|
## Example:
|
33
37
|
```python
|
@@ -0,0 +1,8 @@
|
|
1
|
+
dearpygui_forms/__init__.py,sha256=G_SP5hMol1eeOBLl0Lsphe1yyQ800aaCzI0gp03UagE,104
|
2
|
+
dearpygui_forms/dpg_form.py,sha256=ShdPOPKSjOFS2jC2aG1f_8-c3V3Vhc2JJLrPxqBjvJc,1778
|
3
|
+
dearpygui_forms/exceptions.py,sha256=3ZEGpeCdkIIpH92yoNu6pVcF6HxyFSuWdjAOwfIdVuU,47
|
4
|
+
dearpygui_forms/models.py,sha256=4AisK4HjX1ksZDxiwpZ5PKnFTbIg3Z7gyhFM2OCGfUA,683
|
5
|
+
dearpygui_forms/widgets.py,sha256=ShkQ622lQYjZQzxq3gBXnHuWxpL5m77A9Nq4DX4dwhE,9640
|
6
|
+
dearpygui_forms-0.3.0.dist-info/METADATA,sha256=zVFXnVE7AG1kSNZ8izM3vpXl4nGlYOIGjeROsdRK7W0,1503
|
7
|
+
dearpygui_forms-0.3.0.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
|
8
|
+
dearpygui_forms-0.3.0.dist-info/RECORD,,
|
@@ -1,7 +0,0 @@
|
|
1
|
-
dearpygui_forms/__init__.py,sha256=G_SP5hMol1eeOBLl0Lsphe1yyQ800aaCzI0gp03UagE,104
|
2
|
-
dearpygui_forms/dpg_form.py,sha256=hFSWL3BSc0sxVbA2b-_GLGUPIld1VXkGwImQVs8j3nE,1591
|
3
|
-
dearpygui_forms/models.py,sha256=74CL8WvfY5Qrh-Fx1uSmRU-TY33r_LtFtS1unYqWI5M,636
|
4
|
-
dearpygui_forms/widgets.py,sha256=hZsepjOtJtMloNeOaNVgAzNaTeZoznfPNwS7gnstLyw,6851
|
5
|
-
dearpygui_forms-0.2.0.dist-info/METADATA,sha256=MDdweUUm5niI4vdOvI5b7YRSpB_ss4VS7C1a9Ls01MA,1457
|
6
|
-
dearpygui_forms-0.2.0.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
|
7
|
-
dearpygui_forms-0.2.0.dist-info/RECORD,,
|
File without changes
|