Qt 可编辑树视图-更改编辑字段的类型

Qt 可编辑树视图-更改编辑字段的类型,qt,view,pyqt,pyqt5,Qt,View,Pyqt,Pyqt5,我有这样的字典: {"key1": 1, "key2": 0, "key3": {"key": 1}, "dupa": None} 我想将其编辑为树视图,但无法更改key1以存储字符串 我看见了。然后编辑它以显示我的词典。 下面是一个例子: 请查看读取的“区域”,因为您无法在该字段中插入字符串 所以我的问题是: 我应该重写哪些类或函数以允许显示控件编辑项(我想添加允许更改类型并删除整个项或添加新项的控件)?换句话说:我怎样才能把字符串放在这个字段中 在哪里可以找到此函数/类的原始定义 我使用

我有这样的字典:

{"key1": 1, "key2": 0, "key3": {"key": 1}, "dupa": None}
我想将其编辑为树视图,但无法更改
key1
以存储字符串

我看见了。然后编辑它以显示我的词典。
下面是一个例子:

请查看读取的“区域”,因为您无法在该字段中插入字符串

所以我的问题是:
  • 我应该重写哪些类或函数以允许显示控件编辑项(我想添加允许更改类型并删除整个项或添加新项的控件)?换句话说:我怎样才能把字符串放在这个字段中
  • 在哪里可以找到此函数/类的原始定义

    我使用了<代码> QTTAG,因为您可以回答我的C++示例,我可以把它翻译成Python。 我编辑的代码:(准备好复制和运行)但我认为没有必要看它,来回答我的问题。

    来自PyQt5.QtCore导入(qabstractemmodel、QFile、QIODevice、,
    QItemSelectionModel、QModelIndex、Qt、QAbstractItemModel、QoObject)
    从PyQt5.QtWidgets导入QApplication、QMainWindow、QHBoxLayout
    从PyQt5导入QtCore、QtGui、QtWidgets
    类TreeItem(对象):
    def uuu init uuu(self,data,parent=None):
    self.parentItem=父项
    self.itemData=data#它也是[]
    self.childItems=[]
    def子项(自身,行):
    返回self.childItems[行]
    def儿童计数(自我):
    返回len(self.childItems)
    def儿童编号(自我):
    如果self.parentItem不是无:
    返回self.parentItem.childItems.index(self)
    返回0
    def列计数(自身):
    返回len(self.itemData)
    def数据(自身,列):
    返回self.itemData[列]
    def insertChildren(自身、位置、计数、列):
    如果位置<0或位置>len(self.childItems):
    返回错误
    对于范围内的行(计数):
    数据=[范围(列)中的v无]
    item=TreeItem(数据,自身)
    self.childItems.insert(位置,项目)
    返回真值
    按项目(自身、项目)添加子项目的定义:
    item.parentItem=self
    self.childItems.append(项)
    def appendChild_by_数据(self,data):
    self.childItems.append(TreeItem(数据,self))
    def insertColumns(自身、位置、列):
    如果位置<0或位置>len(self.itemData):
    返回错误
    对于范围内的列(列):
    self.itemData.insert(位置,无)
    对于self.childItems中的子项:
    子.insertColumns(位置、列)
    返回真值
    def父级(自我):
    返回self.parentItem
    def removeChildren(自身、位置、计数):
    如果位置<0或位置+计数>len(self.childItems):
    返回错误
    对于范围内的行(计数):
    self.childItems.pop(位置)
    返回真值
    def removeColumns(自身、位置、列):
    如果位置<0或位置+列>长度(self.itemData):
    返回错误
    对于范围内的列(列):
    self.itemData.pop(位置)
    对于self.childItems中的子项:
    子.removeColumns(位置、列)
    返回真值
    def setData(自身、列、值):
    如果列<0或列>=len(self.itemData):
    返回错误
    self.itemData[列]=值
    返回真值
    类树模型(QAbstractItemModel):
    def uuu init uuuu(self,header,data,parent=None):
    super(树模型,self)。\uuuu init\uuuuu(父级)
    rootData=[标头中标头的标头]
    self.rootItem=TreeItem(rootData)
    self.setupModelData(数据,self.rootItem)
    打印(self.rootItem.childCount())
    def columnCount(self,parent=QModelIndex()):
    返回self.rootItem.columnCount()
    def数据(自身、索引、角色):
    如果不是index.isValid():
    一无所获
    如果角色!=Qt.DisplayRole和role!=Qt.EditRole:
    一无所获
    item=self.getItem(索引)
    返回item.data(index.column())
    def标志(自、索引):
    如果不是index.isValid():
    返回0
    返回Qt.ItemIsEditable | Qt.ItemIsEnabled | Qt.itemisselect
    def getItem(自身,索引):
    如果index.isValid():
    item=index.internalPointer()
    如果项目:
    退货项目
    返回self.rootItem
    def headerData(自身、部分、方向、角色=Qt.DisplayRole):
    如果方向==Qt.Horizontal且角色==Qt.DisplayRole:
    返回self.rootItem.data(部分)
    一无所获
    def索引(self、row、column、parent=QModelIndex()):
    如果parent.isValid()和parent.column()!=0:
    返回QModelIndex()
    parentItem=self.getItem(父项)
    childItem=parentItem.child(行)
    如果是子项:
    返回self.createIndex(行、列、子项)
    其他:
    返回QModelIndex()
    def insertColumns(self、position、columns、parent=QModelIndex()):
    self.beginInsertColumns(父、位置、位置+列-1)
    success=self.rootItem.insertColumns(位置、列)
    self.endInsertColumns()
    回归成功
    def insertRows(self、position、rows、parent=QModelIndex()):
    parentItem=self.getItem(父项)
    self.beginInsertRows(父、位置、位置+行-1)
    success=parentItem.insertChildren(位置、行、,
    self.rootItem.columnCount())
    self.endInsertRows()
    回归成功
    def父级(自我,索引):
    如果不是index.isValid():
    返回QModelIndex()
    childItem=self.getItem(索引)
    parentItem=childItem.parent()
    如果parentItem==self.rootItem:
    返回QModelIndex()
    返回self.createIndex(parentItem.childNumber(),0,parentItem)
    def removeColumns(自身、位置、列
    
    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_())