我有这样的字典:
{"key1": 1, "key2": 0, "key3": {"key": 1}, "dupa": None}
我想将其编辑为树视图,但我无法更改key1
来存储字符串。
我看到了editable model view example。并编辑它以显示我的字典 这是一个例子:
查看读取的“区域”,因为您可以预期无法在此字段中插入字符串。
所以我的问题是:我使用了qt
标记,因为您可以在C ++示例中回答我的问题,我可以将其翻译为python。
from PyQt5.QtCore import (QAbstractItemModel, QFile, QIODevice,
QItemSelectionModel, QModelIndex, Qt, QAbstractItemModel, QObject)
from PyQt5.QtWidgets import QApplication, QMainWindow, QHBoxLayout
from PyQt5 import QtCore, QtGui, QtWidgets
class TreeItem(object):
def __init__(self, data, parent=None):
self.parentItem = parent
self.itemData = data # it's also []
self.childItems = []
def child(self, row):
return self.childItems[row]
def childCount(self):
return len(self.childItems)
def childNumber(self):
if self.parentItem is not None:
return self.parentItem.childItems.index(self)
return 0
def columnCount(self):
return len(self.itemData)
def data(self, column):
return self.itemData[column]
def insertChildren(self, position, count, columns):
if position < 0 or position > len(self.childItems):
return False
for row in range(count):
data = [None for v in range(columns)]
item = TreeItem(data, self)
self.childItems.insert(position, item)
return True
def appendChild_by_item(self, item):
item.parentItem = self
self.childItems.append(item)
def appendChild_by_data(self, data):
self.childItems.append(TreeItem(data, self))
def insertColumns(self, position, columns):
if position < 0 or position > len(self.itemData):
return False
for column in range(columns):
self.itemData.insert(position, None)
for child in self.childItems:
child.insertColumns(position, columns)
return True
def parent(self):
return self.parentItem
def removeChildren(self, position, count):
if position < 0 or position + count > len(self.childItems):
return False
for row in range(count):
self.childItems.pop(position)
return True
def removeColumns(self, position, columns):
if position < 0 or position + columns > len(self.itemData):
return False
for column in range(columns):
self.itemData.pop(position)
for child in self.childItems:
child.removeColumns(position, columns)
return True
def setData(self, column, value):
if column < 0 or column >= len(self.itemData):
return False
self.itemData[column] = value
return True
class TreeModel(QAbstractItemModel):
def __init__(self, headers, data, parent=None):
super(TreeModel, self).__init__(parent)
rootData = [header for header in headers]
self.rootItem = TreeItem(rootData)
self.setupModelData(data, self.rootItem)
print(self.rootItem.childCount())
def columnCount(self, parent=QModelIndex()):
return self.rootItem.columnCount()
def data(self, index, role):
if not index.isValid():
return None
if role != Qt.DisplayRole and role != Qt.EditRole:
return None
item = self.getItem(index)
return item.data(index.column())
def flags(self, index):
if not index.isValid():
return 0
return Qt.ItemIsEditable | Qt.ItemIsEnabled | Qt.ItemIsSelectable
def getItem(self, index):
if index.isValid():
item = index.internalPointer()
if item:
return item
return self.rootItem
def headerData(self, section, orientation, role=Qt.DisplayRole):
if orientation == Qt.Horizontal and role == Qt.DisplayRole:
return self.rootItem.data(section)
return None
def index(self, row, column, parent=QModelIndex()):
if parent.isValid() and parent.column() != 0:
return QModelIndex()
parentItem = self.getItem(parent)
childItem = parentItem.child(row)
if childItem:
return self.createIndex(row, column, childItem)
else:
return QModelIndex()
def insertColumns(self, position, columns, parent=QModelIndex()):
self.beginInsertColumns(parent, position, position + columns - 1)
success = self.rootItem.insertColumns(position, columns)
self.endInsertColumns()
return success
def insertRows(self, position, rows, parent=QModelIndex()):
parentItem = self.getItem(parent)
self.beginInsertRows(parent, position, position + rows - 1)
success = parentItem.insertChildren(position, rows,
self.rootItem.columnCount())
self.endInsertRows()
return success
def parent(self, index):
if not index.isValid():
return QModelIndex()
childItem = self.getItem(index)
parentItem = childItem.parent()
if parentItem == self.rootItem:
return QModelIndex()
return self.createIndex(parentItem.childNumber(), 0, parentItem)
def removeColumns(self, position, columns, parent=QModelIndex()):
self.beginRemoveColumns(parent, position, position + columns - 1)
success = self.rootItem.removeColumns(position, columns)
self.endRemoveColumns()
if self.rootItem.columnCount() == 0:
self.removeRows(0, self.rowCount())
return success
def removeRows(self, position, rows, parent=QModelIndex()):
parentItem = self.getItem(parent)
self.beginRemoveRows(parent, position, position + rows - 1)
success = parentItem.removeChildren(position, rows)
self.endRemoveRows()
return success
def rowCount(self, parent=QModelIndex()):
parentItem = self.getItem(parent)
return parentItem.childCount()
def setData(self, index, value, role=Qt.EditRole):
if role != Qt.EditRole:
return False
item = self.getItem(index)
result = item.setData(index.column(), value)
if result:
self.dataChanged.emit(index, index)
return result
def setHeaderData(self, section, orientation, value, role=Qt.EditRole):
if role != Qt.EditRole or orientation != Qt.Horizontal:
return False
result = self.rootItem.setData(section, value)
if result:
self.headerDataChanged.emit(orientation, section, section)
return result
def setupModelData(self, nested_dict, parent):
print(nested_dict)
for k, v in nested_dict.items():
if isinstance(v, dict):
parent.appendChild_by_data([k, None])
self.setupModelData(v, parent.child(parent.childCount() - 1))
else:
parent.appendChild_by_data([k, v])
class MainWindow(QMainWindow):
"""docstring for MainWindow"""
def __init__(self, data, parent=None):
super(MainWindow, self).__init__(parent=None)
headersLabels = ("Key", "value")
self.orginal_data = data
print(data)
self.m_model = TreeModel(headersLabels, data)
self.container = QtWidgets.QWidget()
self.m_view = QtWidgets.QTreeView()
self.m_view.setModel(self.m_model)
self.testButton = QtWidgets.QPushButton("Test")
self.testButton.clicked.connect(self.testAction)
self.buttonLayout = QHBoxLayout()
self.buttonLayout.addWidget(self.testButton)
self.container_layout = QtWidgets.QVBoxLayout()
self.container_layout.addWidget(self.m_view)
self.container_layout.addLayout(self.buttonLayout)
self.container.setLayout(self.container_layout)
self.setCentralWidget(self.container)
def testAction(self):
selceteds = self.m_view.selectedIndexes()
print(selceteds)
for i in selceteds:
item = self.m_model.getItem(i)
print(item.data(i.column()))
if __name__ == '__main__':
import sys
_d = {"key1": 1, "key2": 0, "key3": {"key": 1}, "dupa": None}
app = QApplication(sys.argv)
window = MainWindow(_d)
window.show()
sys.exit(app.exec_())
我希望我的英语足够了解
答案 0 :(得分:2)
如果您不喜欢内置代理提供的编辑器,则需要实现自定义delegate来修改模型项。
在您的情况下,您需要创建QStyledItemDelegate的子类并重新实现方法createEditor(很可能您希望从中返回QLineEdit
),{{ 3}}(设置从数字转换为编辑器的字符串),setEditorData(设置从字符串转换回模型的数字)。然后,您需要将代理设置为视图。
您可能希望查看setModelData示例,但您的用例似乎更简单:您不需要重新实现项目绘制。