我正在尝试在 Python 中将列表包装在 QAbstractItemModel 中,以允许我使用 PyQt 附带的 GUI 优势将列表视为树。准确地说,我使用的是 PyQt5 和 Python 3.3。
我试图显式地生成指向列表项的指针,但在识别父项时遇到了麻烦。我没有分配它们,我不确定 PyQt 在执行 createIndex 时如何或是否分配它们。然后我决定重写代码以明确识别使用索引(行值)访问的项目,例如给定嵌套列表 ["A",["a",[1,2,3]],"B", "C",["b",[4,5,6],"d"]] 然后我可以使用 [4,1,1] 指向 5,然后使用相同的列表减去最后一项来检索父项, [4,1]。
我的问题是这个。当我使用从行值生成的列表时,CREATEINDEX 方法会使代码崩溃。我的最小损坏示例(MBE)如下。取消注释其中带有“return self.createIndex(row,col,ptr)”的两行,以查看我描述的细分。
from PyQt5.QtGui import QFont, QColor
from PyQt5.QtCore import QAbstractItemModel, QModelIndex, Qt, QAbstractListModel, QAbstractTableModel, QSize, QVariant
from PyQt5.QtWidgets import QApplication, QTreeView, QTableView, QListView
class NodeTree(QAbstractItemModel) :
def __init__(self,parent,data) :
super(NodeTree,self).__init__(parent)
self.data = data
def rowCount(self, parent = QModelIndex()) :
# int rowCount (self, QModelIndex parent = QModelIndex())
if parent.isValid() :
data = self.data
for idx in parent.internalPointer() :
data = data[idx]
return len(data)
else :
return len(self.data)
def columnCount(self, parent = QModelIndex()) :
# int columnCount (self, QModelIndex parent = QModelIndex())
return 1
def data(self, index = QModelIndex(), role = None) :
# QVariant data (self, QModelIndex index, int role = Qt.DisplayRole)
if role == 0 :
if index.isValid() :
return str(index.internalPointer())
else :
return "No Data"
return None
def index(self,row,col, parent = QModelIndex()):
# QModelIndex index (self, int row, int column, QModelIndex parent = QModelIndex())
# QModelIndex createIndex (self, int arow, int acolumn, int aid)
# QModelIndex createIndex (self, int arow, int acolumn, object adata = 0)
if parent.isValid() :
ptr = [parent.internalPointer(),row]
# return self.createIndex(row,col,ptr)
return QModelIndex()
else :
ptr = [row]
# return self.createIndex(row,col,ptr)
return QModelIndex()
return QModelIndex()
def parent(self, child = QModelIndex()):
# QObject parent (self)
if child.isValid() :
print(child.internalPointer())
return QModelIndex()
if __name__ == "__main__" :
# http://blog.mathieu-leplatre.info/filesystem-watch-with-pyqt4.html
import sys
app = QApplication(sys.argv)
TreeView = QTreeView()
TreeModel = NodeTree(TreeView, [['A',['a',1]],['C','D'],['E','F']])
TreeView.setModel(TreeModel)
TreeView.show()
app.exec_()
我不明白 QModelIndex 是如何在 CREATEINDEX 中创建的,为什么它会在 INDEX 方法中动态生成的列表崩溃。对我来说,应该在调用之间保留 INTERNALPOINTER,然后传递一个列表就可以了。
让我感到困惑的另一件事是何时以及为什么调用父级和索引。据我了解,索引向下遍历树,父级向上遍历。因此,对 INDEX 的调用在 (row,col) 处标识父级的子级,而 PARENT 是一个子级并确定父级。是参照内部指针完成的吗?如果是这样,为什么 QmodelIndex 会维护它自己的 PARENT 方法。似乎 Qt 维护它自己的内部树,它根据索引和父项之间的调用建立项目之间的层次结构。那就是总是有两棵树,一棵用于我的模型,一棵用于展示。