-
Notifications
You must be signed in to change notification settings - Fork 6
/
Copy pathqjsonmodel.py
201 lines (160 loc) · 5.26 KB
/
qjsonmodel.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
"""
The model class used for populating the QJsonView,
and providing functionalities to manipulate QJsonNode objects within the model
"""
from Qt import QtWidgets, QtCore, QtGui
from .qjsonnode import QJsonNode
class QJsonModel(QtCore.QAbstractItemModel):
sortRole = QtCore.Qt.UserRole
filterRole = QtCore.Qt.UserRole + 1
def __init__(self, root, parent=None):
"""
Initialization
:param root: QJsonNode. root node of the model, it is hidden
"""
super(QJsonModel, self).__init__(parent)
self._rootNode = root
def rowCount(self, parent=QtCore.QModelIndex()):
"""
Override
"""
if not parent.isValid():
parentNode = self._rootNode
else:
parentNode = parent.internalPointer()
return parentNode.childCount
def columnCount(self, parent=QtCore.QModelIndex()):
"""
Override
"""
return 2
def data(self, index, role):
"""
Override
"""
node = self.getNode(index)
if role == QtCore.Qt.DisplayRole:
if index.column() == 0:
return node.key
elif index.column() == 1:
return node.value
elif role == QtCore.Qt.EditRole:
if index.column() == 0:
return node.key
elif index.column() == 1:
return node.value
elif role == QJsonModel.sortRole:
return node.key
elif role == QJsonModel.filterRole:
return node.key
elif role == QtCore.Qt.SizeHintRole:
return QtCore.QSize(-1, 22)
def setData(self, index, value, role):
"""
Override
"""
node = self.getNode(index)
if role == QtCore.Qt.EditRole:
if index.column() == 0:
node.key = value
self.dataChanged.emit(index, index)
return True
if index.column() == 1:
node.value = value
self.dataChanged.emit(index, index)
return True
return False
def headerData(self, section, orientation, role):
"""
Override
"""
if role == QtCore.Qt.DisplayRole:
if section == 0:
return "Key"
elif section == 1:
return "Value"
def flags(self, index):
"""
Override
"""
flags = super(QJsonModel, self).flags(index)
return (QtCore.Qt.ItemIsEditable
| QtCore.Qt.ItemIsDragEnabled
| QtCore.Qt.ItemIsDropEnabled
| flags)
def index(self, row, column, parent=QtCore.QModelIndex()):
"""
Override
"""
if not self.hasIndex(row, column, parent):
return QtCore.QModelIndex()
parentNode = self.getNode(parent)
currentNode = parentNode.child(row)
if currentNode:
return self.createIndex(row, column, currentNode)
else:
return QtCore.QModelIndex()
def parent(self, index):
"""
Override
"""
currentNode = self.getNode(index)
parentNode = currentNode.parent
if parentNode == self._rootNode:
return QtCore.QModelIndex()
return self.createIndex(parentNode.row(), 0, parentNode)
def addChildren(self, children, parent=QtCore.QModelIndex()):
"""
Custom: add children QJsonNode to the specified index
"""
self.beginInsertRows(parent, 0, len(children) - 1)
if parent == QtCore.QModelIndex():
parentNode = self._rootNode
else:
parentNode = parent.internalPointer()
for child in children:
parentNode.addChild(child)
self.endInsertRows()
return True
def removeChild(self, position, parent=QtCore.QModelIndex()):
"""
Custom: remove child of position for the specified index
"""
self.beginRemoveRows(parent, position, position)
if parent == QtCore.QModelIndex():
parentNode = self._rootNode
else:
parentNode = parent.internalPointer()
parentNode.removeChild(position)
self.endRemoveRows()
return True
def clear(self):
"""
Custom: clear the model data
"""
self.beginResetModel()
self._rootNode = QJsonNode()
self.endResetModel()
return True
def getNode(self, index):
"""
Custom: get QJsonNode from model index
:param index: QModelIndex. specified index
"""
if index.isValid():
currentNode = index.internalPointer()
if currentNode:
return currentNode
return self._rootNode
def asDict(self, index=QtCore.QModelIndex()):
"""
Custom: serialize specified index to dictionary
if no index is specified, the whole model will be serialized
but will not include the root key (as it's supposed to be hidden)
:param index: QModelIndex. specified index
:return: dict. output dictionary
"""
node = self.getNode(index)
if node == self._rootNode:
return node.asDict().values()[0]
return node.asDict()