Skip to content

Commit 5daa65e

Browse files
committed
KoreUI - Implemented 'Get Value' for each widget and for the form
1 parent c39ceb4 commit 5daa65e

File tree

3 files changed

+87
-39
lines changed

3 files changed

+87
-39
lines changed

example_schema.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
{"title": "Complex Form Example",
1+
{
2+
"title": "Complex Form Example",
23
"description": "This form demonstrates various JSON Schema features including arrays of oneOf",
34
"type": "object",
45
"required": ["name", "age", "contacts", "preferences"],
740 Bytes
Binary file not shown.

src/koreui.py

Lines changed: 85 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,14 @@
11
from PySide6.QtWidgets import (
22
QWidget, QVBoxLayout, QHBoxLayout, QLabel, QLineEdit, QSpinBox,
3-
QDoubleSpinBox, QComboBox, QCheckBox, QGroupBox, QPushButton,
4-
QApplication, QScrollArea, QTextEdit, QDateEdit, QTimeEdit,
5-
QDateTimeEdit, QTabWidget, QFrame, QSplitter, QTreeWidget,
6-
QTreeWidgetItem, QHeaderView, QFormLayout, QMessageBox,
7-
QStackedWidget, QSlider, QProgressBar, QDial, QLCDNumber,
8-
QListWidget, QListWidgetItem, QTableWidget, QTableWidgetItem
3+
QDoubleSpinBox, QComboBox, QCheckBox, QPushButton, QScrollArea,
4+
QTextEdit, QDateEdit, QTimeEdit, QDateTimeEdit, QFrame, QMessageBox,
5+
QStackedWidget
96
)
10-
from PySide6.QtCore import Qt, QDate, QTime, QDateTime, QTimer, Signal, QObject, QUrl, QCoreApplication
11-
from PySide6.QtGui import QValidator, QRegularExpressionValidator, QFont, QPalette, QColor
7+
from PySide6.QtCore import Qt, QDate, QTime, QDateTime, Signal
8+
from PySide6.QtGui import QRegularExpressionValidator
129
import json
1310
import re
14-
import uuid
15-
import base64
16-
from datetime import datetime, date, time
17-
from typing import Any, Dict, List, Optional, Union, Callable, Set
11+
from typing import Any, Dict, List, Optional, Union, Callable
1812
from urllib.parse import urlparse
1913
import ipaddress
2014
import email.utils
@@ -171,6 +165,7 @@
171165
}
172166
"""
173167

168+
174169
class ValidationError:
175170
"""Custom validation error class (not an Exception)"""
176171
def __init__(self, message: str, path: str = "", schema_path: str = ""):
@@ -648,6 +643,8 @@ def validate_value(self) -> List[ValidationError]:
648643
"""Validate current value against schema"""
649644
try:
650645
value = self.get_value()
646+
if value is None and self.schema.get("type") == "array":
647+
value = []
651648
return self.validator.validate(value, self.schema, self.path)
652649
except Exception as e:
653650
return [ValidationError(str(e), self.path)]
@@ -1043,7 +1040,32 @@ def update_controls(self):
10431040

10441041
def get_value(self) -> List[Any]:
10451042
"""Get array values"""
1046-
return [widget.get_value() for widget in self.item_widgets]
1043+
values = []
1044+
for i in range(self.items_layout.count() - 1):
1045+
item_container = self.items_layout.itemAt(i).widget()
1046+
if not item_container:
1047+
continue
1048+
1049+
container_layout = item_container.layout()
1050+
if not container_layout:
1051+
continue
1052+
1053+
widget_item = container_layout.itemAt(1)
1054+
if not widget_item:
1055+
continue
1056+
1057+
item_widget = widget_item.widget()
1058+
if not hasattr(item_widget, 'get_value'):
1059+
continue
1060+
1061+
try:
1062+
value = item_widget.get_value()
1063+
if value is not None:
1064+
values.append(value)
1065+
except Exception as e:
1066+
print(f"Error getting array item value: {e}")
1067+
1068+
return values
10471069

10481070
def set_value(self, value: List[Any]):
10491071
"""Set array values"""
@@ -1207,31 +1229,39 @@ def _validate_object(self, data: Dict, schema: Dict, path: str, errors: List[Val
12071229
errors.append(ValidationError(f"Required property '{prop_name}' is missing", path))
12081230

12091231
def get_value(self) -> Dict[str, Any]:
1210-
result = {}
1211-
for prop_name, widget in self.property_widgets.items():
1212-
try:
1213-
value = widget.get_value()
1214-
if value is not None:
1215-
# Filter keys that are actually in the current schema
1216-
if prop_name in self.schema.get("properties", {}):
1217-
prop_schema = self.schema["properties"][prop_name]
1218-
1219-
# If this is a conditional schema, apply its 'if' to see if 'then' or 'else' is active
1220-
if "if" in prop_schema and isinstance(widget, ConditionalWidget):
1221-
try:
1222-
active_value = value
1223-
allowed_keys = set(widget._current_schema.get("properties", {}).keys()) if widget._current_schema else set()
1224-
if isinstance(active_value, dict):
1225-
active_value = {k: v for k, v in active_value.items() if k in allowed_keys}
1226-
result[prop_name] = active_value
1227-
except Exception as e:
1228-
print(f"Error filtering conditional value for {prop_name}: {e}")
1229-
else:
1230-
result[prop_name] = value
1231-
except Exception as e:
1232-
print(f"Error getting value for {prop_name}: {e}")
1233-
return result
1234-
1232+
result = {}
1233+
for prop_name, widget in self.property_widgets.items():
1234+
if widget is None or not hasattr(widget, 'get_value'):
1235+
continue
1236+
1237+
try:
1238+
# Check if widget is properly initialized
1239+
if not widget.isVisible() and isinstance(widget, (OneOfWidget, AnyOfWidget)):
1240+
continue
1241+
1242+
value = widget.get_value()
1243+
if value is not None:
1244+
# Filter keys that are actually in the current schema
1245+
if prop_name in self.schema.get("properties", {}):
1246+
prop_schema = self.schema["properties"][prop_name]
1247+
1248+
# Handle conditional schemas
1249+
if "if" in prop_schema and isinstance(widget, ConditionalWidget):
1250+
try:
1251+
active_value = value
1252+
allowed_keys = set(widget._current_schema.get("properties", {}).keys()) if widget._current_schema else set()
1253+
if isinstance(active_value, dict):
1254+
active_value = {k: v for k, v in active_value.items() if k in allowed_keys}
1255+
result[prop_name] = active_value
1256+
except Exception:
1257+
pass
1258+
else:
1259+
result[prop_name] = value
1260+
except Exception:
1261+
pass
1262+
1263+
return result
1264+
12351265
def set_value(self, value: Dict[str, Any]):
12361266
if not isinstance(value, dict):
12371267
return
@@ -1352,6 +1382,23 @@ def _get_parent_context(self) -> Dict[str, Any]:
13521382
except:
13531383
return {}
13541384

1385+
def get_value(self) -> Any:
1386+
current_index = self.selector.currentIndex()
1387+
if 0 <= current_index < len(self.option_widgets):
1388+
current_widget = self.option_widgets[current_index]
1389+
try:
1390+
value = current_widget.get_value()
1391+
if isinstance(value, dict):
1392+
schema_option = self.schema["oneOf"][current_index]
1393+
if "properties" in schema_option and "type" in schema_option["properties"]:
1394+
type_value = schema_option["properties"]["type"].get("const")
1395+
if type_value:
1396+
value["type"] = type_value
1397+
return value
1398+
except Exception as e:
1399+
print(f"Error getting oneOf value: {e}")
1400+
return None
1401+
13551402
def set_value(self, value: Any):
13561403
"""Enhanced value setting with better matching"""
13571404
best_match_index = 0

0 commit comments

Comments
 (0)