| 193 | |
| 194 | |
| 195 | class QJsonModel(QStandardItemModel): |
| 196 | def __init__( |
| 197 | self, |
| 198 | parent: QObject = None, |
| 199 | data: dict = None, |
| 200 | ) -> None: |
| 201 | super().__init__(parent) |
| 202 | self.setHorizontalHeaderLabels(["Key", "Value"]) |
| 203 | self.loadData(data) |
| 204 | |
| 205 | def loadFile( |
| 206 | self, file: str, encoding: str = "utf-8", errors: str = "ignore" |
| 207 | ) -> bool: |
| 208 | with open(file, "rb") as f: |
| 209 | return self.loadJson(f.read().decode(encoding=encoding, errors=errors)) |
| 210 | |
| 211 | def loadJson(self, string: str) -> bool: |
| 212 | return self.loadData(json.loads(string)) |
| 213 | |
| 214 | def loadData(self, data: dict, force: bool = False) -> bool: |
| 215 | if isinstance(data, dict): |
| 216 | if force: |
| 217 | self.clear() |
| 218 | self.__loadData(data) |
| 219 | return True |
| 220 | |
| 221 | return False |
| 222 | |
| 223 | def horizontalHeaderLabels(self) -> List[str]: |
| 224 | return [self.horizontalHeaderItem(i).text() for i in range(self.columnCount())] |
| 225 | |
| 226 | def clear(self): |
| 227 | headers = self.horizontalHeaderLabels() |
| 228 | super().clear() |
| 229 | self.setHorizontalHeaderLabels(headers) |
| 230 | |
| 231 | def findPath( |
| 232 | self, |
| 233 | path: str, |
| 234 | flags=Qt.MatchFixedString |
| 235 | | Qt.MatchCaseSensitive |
| 236 | | Qt.MatchWrap |
| 237 | | Qt.MatchRecursive, |
| 238 | ) -> Union[QJsonItem, None]: |
| 239 | indexes = self.match(self.index(0, 0), QJsonItem.PathRole, path, -1, flags) |
| 240 | indexes = [index for index in indexes if index.isValid()] |
| 241 | return self.itemFromIndex(indexes[0]) if indexes else None # type: ignore |
| 242 | |
| 243 | def updateValue( |
| 244 | self, path: str, value: Any, item: Union[QJsonItem, None] = None |
| 245 | ) -> bool: |
| 246 | item = item or self.findPath(path) |
| 247 | if item is None: |
| 248 | keys = path.split(QJsonItem.Sep) |
| 249 | self.__loadData(reduce(lambda val, key: {key: val}, reversed(keys), value)) |
| 250 | return True |
| 251 | |
| 252 | return item.updateValue(value) |