Model / TableView:行与列

时间:2015-01-11 02:06:09

标签: python qt model pyqt

为了简单易读,这里省略了Qt小部件:

from PyQt4 import QtCore, QtGui
class Node(object):    
    def __init__(self, name, parentNode=None):        
        self.name=name
        self._children=[]
        self._parentNode=parentNode
        if parentNode:
            parentNode._children.append(self)

    def getChildNode(self, row):
        return self._children[row]

    def childrenCount(self):
        return len(self._children)

    def __repr__(self):
        return self.log()
    def log(self, tabLevel=-1):
        output     = ""
        tabLevel += 1
        for i in range(tabLevel):
            output += "\t"
        output += "|------" + self.name + "\n"
        for child in self._children:
            output += child.log(tabLevel)
        tabLevel -= 1
        output += "\n"
        return output

class NodeModel(QtCore.QAbstractItemModel):    
    def __init__(self, parent=None):
        super(NodeModel, self).__init__(parent)

        self._rootNode = Node("Root")
        nodeA0 = Node("nodeA0",  self._rootNode)
        nodeA1 = Node("nodeA1",  nodeA0)
        nodeA2 = Node("nodeA2",  nodeA1)

        nodeB0 = Node("nodeB0",  self._rootNode)
        nodeB1 = Node("nodeB1",  nodeB0)
        nodeB2_0 = Node("nodeB2_0",  nodeB1) 
        nodeB2_1 = Node("nodeB2_1",  nodeB1) 

        print self._rootNode

    def rowCount(self, parentIndex):    
        if not parentIndex.isValid():
            parentNode = self._rootNode
        else:
            parentNode = parentIndex.internalPointer()
        return parentNode.childCount()

    def columnCount(self, parent):   
        return 1

    def data(self, index, role):     
        if not index.isValid():
            return None

        node = index.internalPointer()

        if role == QtCore.Qt.DisplayRole:
            if index.column() == 0:
                return node.name()                  

    def getNode(self, index):    
        if index.isValid():
            node = index.internalPointer()
            if node:
                return node            
        return self._rootNode

    def parent(self, index):   
        node = self.getNode(index)
        parentNode = node._parentNode

        if parentNode == self._rootNode:
            return QtCore.QModelIndex()

        return self.createIndex(parentNode.row(), 0, parentNode)        

    def index(self, row, column, parentIndex):
        print  row, column  
        parentNode = self.getNode(parentIndex)
        childNode = parentNode.getChildNode(row)

        if childNode:
            return self.createIndex(row, column, childNode)
        else:
            return QtCore.QModelIndex()

myModel=NodeModel()

以下是基础数据结构图:

|------Root
    |------nodeA0
        |------nodeA1
            |------nodeA2



    |------nodeB0
        |------nodeB1
            |------nodeB2_0

            |------nodeB2_1

第1步

我首先从第1行和第0列查询顶级QModelIndex

nodeB0_modelIndex=myModel.index(1, 0, QtCore.QModelIndex())

其中1是行号,0是列号,QtCore.QModelIndex()是空的QModelIndex(这就是我们让模型知道我们请求顶部的方式级别 QModelIndex)。

接下来使用QModelIndex .internalPointer()方法我查询链接到收到的QModelIndex的数据变量:

nodeB0=nodeB0_modelIndex.internalPointer()
print 'Confirming: top-level node at row 1 column 0: "%s"'%nodeB0.name

确认打印我得到一个“正确”变量:

  

确认:第1行第0列的顶级节点:“nodeB0”

第2步

现在将顶级QModelIndex链接到“nodeB0”,我可以将数据层次结构向下传播到nodeB1,然后传播到nodeB2_0nodeB2_1。再次查询QModelIndex我将使用myModel.index()方法为其提供三个参数:行号,列号(两个数字都相对于QModelIndex - 父级)和{{1} } -parent本身作为第三个参数:

QModelIndex

到目前为止,我一直只使用行号。对于列号我使用0。 查看我在nodeB1_modelIndex=myModel.index(0, 0, nodeB0_modelIndex) nodeB1=nodeB1_modelIndex.internalPointer() print 'Confirming: node B at row 0 column 0: "%s"'%nodeB1.name nodeB2_0_modelIndex=myModel.index(0, 0, nodeB1_modelIndex) nodeB2_0=nodeB2_0_modelIndex.internalPointer() print 'Confirming: node B at row 0 column 0: "%s"'%nodeB2_0.name nodeB2_1_modelIndex=myModel.index(1, 0, nodeB1_modelIndex) nodeB2_1=nodeB2_1_modelIndex.internalPointer() print 'Confirming: node B at row 1 column 0: "%s"'%nodeB2_1.name 中定义的基础数据结构,我可以看到原因:

模型的行号最终用于查询存储在self._rootNode列表变量中的节点实例:

_children

其中def getChildNode(self, row): return self._children[row] 参数对应于Model的行和列表变量索引号 - 存储在典型列表变量中的有序元素数。

问题:查看我的基础数据结构,我找不到实现数字的方法。我应该如何,在哪里以及为什么要使用Columns?

以后编辑:

当我想到一个想法时,我正在重读我自己的问题...如果我的问题的答案是:当我们打算将节点项垂直放置在QTableView中时,我们使用行号,其中零编号的项目位于第0行和所有其他项目都在下降(因此只有一个列#0在使用中)。如果我们决定水平定位节点项,我们使用列号。这样第一项就是最左边的。并且所有以下项目在右侧彼此相邻放置。然后只使用一行#0。

使用QTableView,我们使用行号或列号。不是两者。因此,我们设计了底层数据结构变量和相应处理它的模型。我是对的吗?

enter image description here

1 个答案:

答案 0 :(得分:1)

如果我理解正确,您有一个要在表视图而不是树视图中显示的树模型。 由于在表格视图中显示数据的最简单方法是使用2D数组([[]]),因此可以使用QAbstractProxyModel将树状数据模型转换为2D数组数据模型。 通过这种方式,实施rowCountcolumnCountdata非常容易。