Hi everyone,

I've got a QTreeView with a custom model which has to handle several items (say 
1 million). I've set the setUniformRowHeights property to True, so when the 
tree is set up the scrolling is very fluid. The problem arises when I try to 
change the ordering of the items. 
The test script attacched illustrates the situation I have to deal with: I use 
the row_id list to map the items to be shown at a given index; I do this in 
order to use my own C-written sorting function to order the items. Now if you 
push the “Shuffle” button (which simulates the sorting) you can see that even 
if the execution time is fast (0.6 sec on my pc), the tree requires several 
seconds to be updated.
Can anyone point me out what I am doing wrong? 

Thanks in advance!
from PyQt4.QtCore import *
from PyQt4.QtGui import *
from random import shuffle
from time import clock

class TreeItem(object) :
    def __init__(self, data, parent=None) :
        self.parentItem = parent
        self.itemData = data
        self.childItems = []

    def appendChild(self, item) :
        self.childItems.append(item)

    def child(self, row) :
        return self.childItems[row]

    def childCount(self) :
        return len(self.childItems)

    def columnCount(self) :
        return len(self.itemData)

    def data(self, column) :
        try :
            return self.itemData[column]
        except IndexError :
            return None

    def parent(self) :
        return self.parentItem

    def row(self) :
        if self.parentItem :
            return self.parentItem.childItems.index(self)
        return 0
    
    
class TreeModel(QAbstractItemModel) :
    def __init__(self, ) :
        QAbstractItemModel.__init__(self)

        self.root = TreeItem(("root",))
        self.fld = TreeItem(("Items",), self.root)
        self.root.appendChild(self.fld)

        self.row_id = []
        for j in xrange(1000000) :
            self.row_id.append(j)
            self.fld.appendChild(TreeItem(("Item"+str(j+1),), self.fld))
        print "Done"
            
    def _ItemFromIndex(self, index) :
        if not index.isValid() :
            return self.root
        item = index.internalPointer()
        if item == self.fld :
            return item
        fld_index = self.createIndex(0, 0, self.fld)
        return self.index(self.row_id[index.row()], 0, 
fld_index).internalPointer()

    def columnCount(self, parent) :
        return 1
        
    def data(self, index, role) :
        item = self._ItemFromIndex(index)
        if role == Qt.DisplayRole :
            return item.data(0)
        
    def flags(self, flag) :
        return (Qt.ItemIsEnabled|Qt.ItemIsUserCheckable|Qt.ItemIsSelectable)
    
    def hasChildren(self, parent=QModelIndex()) :
        if parent.column() > 0 :
            return False
        item = self.root if not parent.isValid() else parent.internalPointer()
        return item.childCount() != 0
    
    def index(self, row, column, parent) :
        if not self.hasIndex(row, column, parent) :
            return QModelIndex()
        
        parent = self.root if not parent.isValid() else parent.internalPointer()
        child = parent.child(row)
        return self.createIndex(row, column, child) if child else QModelIndex()
        
    def parent(self, index):
        if not index.isValid() :
            return QModelIndex()

        child = index.internalPointer()
        parent = child.parent()

        if parent == self.root :
            return QModelIndex()

        return self.createIndex(parent.row(), 0, parent)
    
    def rowCount(self, parent=QModelIndex()) :
        if parent.column() > 0 :
            return 0
        item = self.root if not parent.isValid() else parent.internalPointer()
        return item.childCount()
    

class Tree(QTreeView) :
    def __init__(self, parent, model) :
        QTreeView.__init__(self, parent)
        self.setHeaderHidden(True)
        self.setContextMenuPolicy(Qt.CustomContextMenu)
        self.setUniformRowHeights(True)
        self.setModel(model)
        self.expand(self.model().index(0, 0, QModelIndex()))
               
    def Shuffle(self) :
        t1 = clock()
        shuffle(self.model().row_id)
        self.model().reset()
        self.expand(self.model().index(0, 0, QModelIndex()))
        print "Shuffle time:", clock()-t1
   
class Frame(QWidget) :
    def __init__(self, parent, model=None) :
        super(QWidget, self).__init__(parent)
        
        self.tree = Tree(self, TreeModel())
        self.shuffle_btn = QPushButton("Shuffle")
        self.shuffle_btn.clicked.connect(self.tree.Shuffle)
        
        vbox = QVBoxLayout()
        vbox.setContentsMargins(0, 0, 0, 0)
        vbox.addWidget(self.tree)
        vbox.addWidget(self.shuffle_btn)
        self.setLayout(vbox)
    
if __name__ == "__main__" :
    import sys
    a = QApplication(sys.argv)
    
    dia = Frame(None)
    dia.resize(400, 600)
    dia.show()
    a.exec_()
_______________________________________________
PyQt mailing list    PyQt@riverbankcomputing.com
http://www.riverbankcomputing.com/mailman/listinfo/pyqt

Reply via email to