Skip to content

Commit 2e5e1b4

Browse files
committed
Support enums
1 parent 3a15b43 commit 2e5e1b4

File tree

4 files changed

+90
-35
lines changed

4 files changed

+90
-35
lines changed

qt_jsonschema_form/defaults.py

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
def enum_defaults(schema):
2+
try:
3+
return schema["enum"][0]
4+
except IndexError:
5+
return None
6+
7+
8+
def object_defaults(schema):
9+
return {k: compute_defaults(s) for k, s in schema["properties"].items()}
10+
11+
12+
def array_defaults(schema):
13+
items_schema = schema['items']
14+
if isinstance(items_schema, dict):
15+
return []
16+
17+
return [compute_defaults(s) for s in schema["items"]]
18+
19+
20+
def compute_defaults(schema):
21+
if "default" in schema:
22+
return schema["default"]
23+
24+
# Enum
25+
if "enum" in schema:
26+
return enum_defaults(schema)
27+
28+
schema_type = schema["type"]
29+
30+
if schema_type == "object":
31+
return object_defaults(schema)
32+
33+
elif schema_type == "array":
34+
return array_defaults(schema)
35+
36+
return None

qt_jsonschema_form/form.py

Lines changed: 13 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,9 @@
11
from copy import deepcopy
2-
from typing import Optional
32

4-
from . import widgets
53
from jsonschema.validators import validator_for
6-
7-
8-
# TODO
9-
def compute_defaults(schema):
10-
if "default" in schema:
11-
return schema["default"]
12-
13-
schema_type = schema["type"]
14-
15-
if schema_type == "object":
16-
return {k: compute_defaults(s) for k, s in schema["properties"].items()}
17-
elif schema_type == "array":
18-
items_schema = schema['items']
19-
if isinstance(items_schema, dict):
20-
return []
21-
return [compute_defaults(s) for s in schema["items"]]
22-
23-
return None
4+
\
5+
from . import widgets
6+
from .defaults import compute_defaults
247

258

269
def get_widget_state(schema, state=None):
@@ -35,13 +18,14 @@ def get_schema_type(schema: dict) -> str:
3518

3619
class WidgetBuilder:
3720
default_widget_map = {
38-
"boolean": {"checkbox": widgets.CheckboxWidget},
39-
"object": {"object": widgets.ObjectWidget},
40-
"number": {"spin": widgets.SpinDoubleWidget, "text": widgets.TextWidget},
21+
"boolean": {"checkbox": widgets.CheckboxWidget, "enum": widgets.EnumWidget},
22+
"object": {"object": widgets.ObjectWidget, "enum": widgets.EnumWidget},
23+
"number": {"spin": widgets.SpinDoubleWidget, "text": widgets.TextWidget, "enum": widgets.EnumWidget},
4124
"string": {"textarea": widgets.TextAreaWidget, "text": widgets.TextWidget, "password": widgets.PasswordWidget,
42-
"filepath": widgets.FilepathWidget, "colour": widgets.ColorWidget},
43-
"integer": {"spin": widgets.SpinWidget, "text": widgets.TextWidget, "range": widgets.IntegerRangeWidget},
44-
"array": {"array": widgets.ArrayWidget}
25+
"filepath": widgets.FilepathWidget, "colour": widgets.ColorWidget, "enum": widgets.EnumWidget},
26+
"integer": {"spin": widgets.SpinWidget, "text": widgets.TextWidget, "range": widgets.IntegerRangeWidget,
27+
"enum": widgets.EnumWidget},
28+
"array": {"array": widgets.ArrayWidget, "enum": widgets.EnumWidget}
4529
}
4630

4731
default_widget_variants = {
@@ -86,6 +70,9 @@ def create_widget(self, schema: dict, ui_schema: dict, state=None) -> widgets.Wi
8670
except KeyError:
8771
default_variant = self.default_widget_variants[schema_type]
8872

73+
if "enum" in schema:
74+
default_variant = "enum"
75+
8976
widget_variant = ui_schema.get('ui:widget', default_variant)
9077
widget_cls = self.widget_map[schema_type][widget_variant]
9178

qt_jsonschema_form/widgets.py

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -410,7 +410,6 @@ def _add_item(self, item_state=None):
410410

411411
# Create widget
412412
item_ui_schema = self.ui_schema.get("items", {})
413-
print(item_schema, item_state)
414413
widget = self.widget_builder.create_widget(item_schema, item_ui_schema, item_state)
415414
controls = ArrayControlsWidget()
416415

@@ -484,3 +483,29 @@ def populate_from_schema(self, schema: dict, ui_schema: dict, widget_builder: 'W
484483
widgets[name] = widget
485484

486485
return widgets
486+
487+
488+
class EnumWidget(WidgetMixin, QtWidgets.QComboBox):
489+
490+
@state_property
491+
def state(self):
492+
return self.itemData(self.currentIndex())
493+
494+
@state.setter
495+
def state(self, value):
496+
index = self.findData(value)
497+
if index == -1:
498+
raise ValueError(value)
499+
self.setCurrentIndex(index)
500+
501+
def configure(self):
502+
options = self.schema["enum"]
503+
for i, opt in enumerate(options):
504+
self.addItem(str(opt))
505+
self.setItemData(i, opt)
506+
507+
self.currentIndexChanged.connect(lambda _: self.on_changed.emit(self.state))
508+
509+
def _index_changed(self, index: int):
510+
value = self.itemData(index)
511+
self.on_changed.emit(self.state)

test.py

Lines changed: 15 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -32,16 +32,22 @@
3232
"items": [
3333
{
3434
"type": "string",
35-
"pattern": "[a-zA-Z\-'\s]+"
35+
"pattern": "[a-zA-Z\-'\s]+",
36+
"enum": [
37+
"Jack", "Jill"
38+
]
3639
},
3740
{
3841
"type": "string",
39-
"pattern": "[a-zA-Z\-'\s]+"
40-
}
42+
"pattern": "[a-zA-Z\-'\s]+",
43+
"enum": [
44+
"Alice", "Bob"
45+
]
46+
},
4147
],
4248
"additionalItems": {
4349
"type": "number"
44-
}
50+
},
4551
}
4652
}
4753
}
@@ -60,13 +66,14 @@
6066
"schema_path": "/home/angus/PycharmProjects/qt-jsonschema-form/qt_jsonschema_form/__pycache__/__init__.cpython-37.pyc",
6167
"integerRangeSteps": 60,
6268
"sky_colour": "#8f5902",
63-
# "names": [
64-
# "wer",
65-
# ""
66-
# ]
69+
"names": [
70+
"Jack",
71+
"Bob"
72+
]
6773
}
6874
w.show()
6975
w.on_changed.connect(lambda d: print(dumps(d, indent=4)))
7076

7177
print(w)
7278
app.exec_()
79+

0 commit comments

Comments
 (0)