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