dearpygui-forms 0.2.1__tar.gz → 0.3.0__tar.gz
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-0.2.1 → dearpygui_forms-0.3.0}/PKG-INFO +5 -1
- {dearpygui_forms-0.2.1 → dearpygui_forms-0.3.0}/README.md +4 -0
- {dearpygui_forms-0.2.1 → dearpygui_forms-0.3.0}/pyproject.toml +1 -1
- {dearpygui_forms-0.2.1 → dearpygui_forms-0.3.0}/src/dearpygui_forms/models.py +1 -0
- {dearpygui_forms-0.2.1 → dearpygui_forms-0.3.0}/src/dearpygui_forms/widgets.py +91 -43
- {dearpygui_forms-0.2.1 → dearpygui_forms-0.3.0}/tests/demo.py +4 -2
- dearpygui_forms-0.3.0/tests/jph_demo.py +0 -0
- {dearpygui_forms-0.2.1 → dearpygui_forms-0.3.0}/uv.lock +1 -1
- {dearpygui_forms-0.2.1 → dearpygui_forms-0.3.0}/.gitignore +0 -0
- {dearpygui_forms-0.2.1 → dearpygui_forms-0.3.0}/.python-version +0 -0
- {dearpygui_forms-0.2.1 → dearpygui_forms-0.3.0}/src/dearpygui_forms/__init__.py +0 -0
- {dearpygui_forms-0.2.1 → dearpygui_forms-0.3.0}/src/dearpygui_forms/dpg_form.py +0 -0
- {dearpygui_forms-0.2.1 → dearpygui_forms-0.3.0}/src/dearpygui_forms/exceptions.py +0 -0
- {dearpygui_forms-0.2.1 → dearpygui_forms-0.3.0}/tests/micro_demo.py +0 -0
- {dearpygui_forms-0.2.1 → dearpygui_forms-0.3.0}/tests/test_models.py +0 -0
@@ -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
|
@@ -9,6 +9,8 @@ Generate GUI forms for your Pydantic models.
|
|
9
9
|
|
10
10
|
|
11
11
|
Currently supported Pydantic fields:
|
12
|
+
- nested entities
|
13
|
+
- arrays
|
12
14
|
- str
|
13
15
|
- int
|
14
16
|
- float
|
@@ -16,6 +18,8 @@ Currently supported Pydantic fields:
|
|
16
18
|
- datetime
|
17
19
|
- date
|
18
20
|
- time
|
21
|
+
- anyOf sequences
|
22
|
+
|
19
23
|
|
20
24
|
## Example:
|
21
25
|
```python
|
@@ -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})"
|
@@ -62,6 +62,9 @@ class Widget:
|
|
62
62
|
def get_value(self) -> Any:
|
63
63
|
pass
|
64
64
|
|
65
|
+
def __del__(self):
|
66
|
+
dpg.delete_item(self._root_item)
|
67
|
+
|
65
68
|
|
66
69
|
class ObjectWidget(Widget):
|
67
70
|
def __init__(self, schema, defs, **kwargs):
|
@@ -72,6 +75,7 @@ class ObjectWidget(Widget):
|
|
72
75
|
for property_name, property in self.schema.properties.items():
|
73
76
|
property_widget = generate_widget(property, self._defs, generate_object=False)
|
74
77
|
property_widget.add()
|
78
|
+
dpg.add_spacer(height=10)
|
75
79
|
self._properties[property_name] = property_widget
|
76
80
|
|
77
81
|
def get_value(self) -> dict[str, Any]:
|
@@ -82,9 +86,69 @@ class ObjectWidget(Widget):
|
|
82
86
|
property_widget.set_value(value.get(property_name))
|
83
87
|
|
84
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
|
+
|
85
118
|
class ArrayWidget(Widget):
|
86
119
|
def __init__(self, schema, defs, **kwargs):
|
87
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
|
+
|
88
152
|
|
89
153
|
|
90
154
|
class MultiTypeWidget(Widget):
|
@@ -94,25 +158,26 @@ class MultiTypeWidget(Widget):
|
|
94
158
|
self._widgets: dict[str, Widget] = {}
|
95
159
|
for type_schema in schema.anyOf:
|
96
160
|
widget = generate_widget(type_schema, defs, generate_object=False)
|
97
|
-
self._widgets[widget.schema.type] = widget
|
161
|
+
self._widgets[widget.schema.title or widget.schema.type] = widget
|
98
162
|
|
99
163
|
super().__init__(schema, defs, **kwargs)
|
100
164
|
|
101
165
|
def _ui(self):
|
102
166
|
with dpg.group(horizontal=True):
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
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:
|
111
177
|
for widget in self._widgets.values():
|
112
178
|
widget.add(hidden=True)
|
113
179
|
|
114
|
-
def switch_value_type(self):
|
115
|
-
new_type = dpg.get_value(self._type_switcher_id)
|
180
|
+
def switch_value_type(self, new_type):
|
116
181
|
if self._widget is not None:
|
117
182
|
self._widget.hide()
|
118
183
|
self._widget = self._widgets[new_type]
|
@@ -135,7 +200,9 @@ class StringWidget(Widget):
|
|
135
200
|
super().__init__(schema, defs, **kwargs)
|
136
201
|
|
137
202
|
def _ui(self):
|
138
|
-
|
203
|
+
if self.schema.title:
|
204
|
+
dpg.add_text(self.schema.title)
|
205
|
+
dpg.add_input_text(tag=self._input_id)
|
139
206
|
|
140
207
|
def get_value(self):
|
141
208
|
return dpg.get_value(self._input_id)
|
@@ -150,7 +217,9 @@ class IntegerWidget(Widget):
|
|
150
217
|
super().__init__(schema, defs, **kwargs)
|
151
218
|
|
152
219
|
def _ui(self):
|
153
|
-
|
220
|
+
if self.schema.title:
|
221
|
+
dpg.add_text(self.schema.title)
|
222
|
+
dpg.add_input_int(tag=self._input_id)
|
154
223
|
|
155
224
|
def get_value(self):
|
156
225
|
return dpg.get_value(self._input_id)
|
@@ -165,7 +234,9 @@ class NumberWidget(Widget):
|
|
165
234
|
super().__init__(schema, defs, **kwargs)
|
166
235
|
|
167
236
|
def _ui(self):
|
168
|
-
|
237
|
+
if self.schema.title:
|
238
|
+
dpg.add_text(self.schema.title)
|
239
|
+
dpg.add_input_float(tag=self._input_id)
|
169
240
|
|
170
241
|
def get_value(self):
|
171
242
|
return dpg.get_value(self._input_id)
|
@@ -180,7 +251,9 @@ class BooleanWidget(Widget):
|
|
180
251
|
super().__init__(schema, defs, **kwargs)
|
181
252
|
|
182
253
|
def _ui(self):
|
183
|
-
|
254
|
+
if self.schema.title:
|
255
|
+
dpg.add_text(self.schema.title)
|
256
|
+
dpg.add_checkbox(tag=self._checkbox_id)
|
184
257
|
|
185
258
|
def get_value(self):
|
186
259
|
return dpg.get_value(self._checkbox_id)
|
@@ -194,7 +267,9 @@ class NoneWidget(Widget):
|
|
194
267
|
super().__init__(schema, defs, **kwargs)
|
195
268
|
|
196
269
|
def _ui(self):
|
197
|
-
|
270
|
+
if self.schema.title:
|
271
|
+
dpg.add_text(self.schema.title)
|
272
|
+
dpg.add_text("<None>", color=(128, 128, 128))
|
198
273
|
|
199
274
|
def get_value(self):
|
200
275
|
return None
|
@@ -203,32 +278,6 @@ class NoneWidget(Widget):
|
|
203
278
|
pass
|
204
279
|
|
205
280
|
|
206
|
-
class ExternalWidget(Widget):
|
207
|
-
def __init__(self, schema, defs, **kwargs):
|
208
|
-
self._external_id = dpg.generate_uuid()
|
209
|
-
self._widget: Widget | None = None
|
210
|
-
super().__init__(schema, defs, **kwargs)
|
211
|
-
|
212
|
-
def _ui(self):
|
213
|
-
with dpg.tree_node(label=self.schema.title) as self._form:
|
214
|
-
self._edit_button = dpg.add_button(label=f"Edit", callback=self.show_object_form)
|
215
|
-
|
216
|
-
def show_object_form(self):
|
217
|
-
if self._widget is None:
|
218
|
-
dpg.delete_item(self._edit_button)
|
219
|
-
self._widget = ObjectWidget(self.schema, self._defs)
|
220
|
-
self._widget.add(parent=self._form)
|
221
|
-
|
222
|
-
def get_value(self):
|
223
|
-
if self._widget is None:
|
224
|
-
raise DearpyguiFormsError(f"{self.schema.title}: set up object.")
|
225
|
-
return self._widget.get_value()
|
226
|
-
|
227
|
-
def set_value(self, value):
|
228
|
-
self.show_object_form()
|
229
|
-
self._widget.set_value(value)
|
230
|
-
|
231
|
-
|
232
281
|
def generate_widget(json_schema: dict[str, Any], defs: dict[str, Any], generate_object: bool = True, **kwargs) -> Widget:
|
233
282
|
schema = PropertySchema(dereference_property(json_schema, defs))
|
234
283
|
match schema:
|
@@ -238,7 +287,6 @@ def generate_widget(json_schema: dict[str, Any], defs: dict[str, Any], generate
|
|
238
287
|
else:
|
239
288
|
return ExternalWidget(schema, defs, **kwargs)
|
240
289
|
case PropertySchema(type='array'):
|
241
|
-
raise NotImplementedError("ArrayWidget is not implemented yet")
|
242
290
|
return ArrayWidget(schema, defs, **kwargs)
|
243
291
|
case PropertySchema(type='string'):
|
244
292
|
return StringWidget(schema, defs, **kwargs)
|
@@ -1,6 +1,6 @@
|
|
1
1
|
import datetime
|
2
2
|
import decimal
|
3
|
-
from pprint import pprint
|
3
|
+
from pprint import pformat, pprint
|
4
4
|
import dearpygui.dearpygui as dpg
|
5
5
|
|
6
6
|
import dearpygui.dearpygui as dpg
|
@@ -25,10 +25,11 @@ class User(BaseModel):
|
|
25
25
|
fingers_on_the_hand: int = 5
|
26
26
|
weight: float = 60.0
|
27
27
|
pi: decimal.Decimal = decimal.Decimal('3.1415')
|
28
|
-
male: bool|None = True
|
28
|
+
male: bool|None|int = True
|
29
29
|
tool: Tool = Field(title="Gun", default=Tool(name="Gun00", price=100.0, quantity=1))
|
30
30
|
best_friend: 'User | None' = Field(title='Best friend')
|
31
31
|
zero: None
|
32
|
+
tools: list[int | Tool | None]
|
32
33
|
# friends: list['User']
|
33
34
|
|
34
35
|
|
@@ -63,6 +64,7 @@ def main():
|
|
63
64
|
dpg.add_menu_item(label='About', callback=dpg.show_about)
|
64
65
|
|
65
66
|
with dpg.window(label="Template", width=641, height=480):
|
67
|
+
logger.debug(f"{pformat(User.model_json_schema())}")
|
66
68
|
UserForm(lambda x: logger.success(x)).add()
|
67
69
|
|
68
70
|
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|