[PyQt] model/view/delegate: data() method called too many times? Performance problem (TP)

Erik Janssens tw55413 at gmail.com
Fri May 15 12:08:27 BST 2009


data it is called multiple times on the same cell, but for a
different role (eg : it is called once to get the text to display,
and another time to get the font size).

but you must make sure the data method returns very fast,
because it will get called a lot, since the view itself contains
no data, so each time a repaint of a cell is needed, the data
method will get called.


> Message: 2
> Date: Thu, 14 May 2009 21:21:30 +0200
> From: TP <paratribulations at free.fr>
> Subject: [PyQt] model/view/delegate: data() method called too many
>        times?  Performance problem
> To: pyqt at riverbankcomputing.com
> Message-ID: <qi7ud6-rgq.ln1 at rama.fbx.proxad.net>
> Content-Type: text/plain; charset=us-ascii
>
> Hi everybody,
>
> I use model/view/delegate architecture of Qt.
> I have a problem of slowness in a small example given below. Run the script
> from a terminal to see all standard output.
> Try to play with the tree: expand items, click on cells, etc. You will find
> that the function "data" is called all the time by Qt. Too many times, I
> think. For example, we get on standard output sequences as:
>
> data, col=1, row=2
> data, col=1, row=2
> data, col=1, row=2
> data, col=1, row=2
> data, col=1, row=2
> data, col=1, row=2
> data, col=1, row=2
>
> which means that the data function is called several times for the same
> cell! Why? It slows down a lot my "real world" application, which is much
> more complicated than this simple script.
>
> How to modify this "greedy" behavior of Qt?
>
> Thanks a lot
>
> Julien
>
>
> ######################################"
> #!/usr/bin/env python
> # -*- coding: utf-8 -*-
>
> from PyQt4.QtCore import *
> from PyQt4.QtGui import *
> import sys
>
>
> class CustomProxyModel( QSortFilterProxyModel ):
>
>    def filterAcceptsRow( self
>            , source_row
>            , source_parent_index ):
>
>        return True
>
>
> class TreeROModel( QAbstractItemModel ):
>
>
>    def __init__( self
>            , parent = None ):
>
>        super( TreeROModel, self ).__init__( parent )
>        self.root = "toto"
>        self.children = [
>                "coco"
>                , "line 1" ]
>        self.children_offirstline = [
>                "coucou" ]
>        self.columncount = 2
>
>
>
>    def rowCount( self, parent ):
>
>        node = self.nodeFromIndex( parent )
>        if node == self.root:
>            return len( self.children )
>        elif node == "coco":
>            return 1
>        else:
>            return 0
>
>
>    def columnCount( self, QModelIndex = None ):
>
>        return 2
>        return self.columncount
>
>
>    def data( self, index, role ):
>
>        content = None
>        col = index.column()
>        row = index.row()
>        print "data, col=%i, row=%i" % (col, row)
>        if role == Qt.DisplayRole:
>            if col == 0:
>                content = self.nodeFromIndex( index )
>            elif row == 0:
>                content = len( self.children ) - 1
>
>            else:
>                content = "nothing in this item"
>
>        elif role == Qt.TextAlignmentRole:
>
>            if col == 0:
>                content = int( Qt.AlignTop|Qt.AlignLeft )
>            else:
>                content = int( Qt.AlignTop|Qt.AlignRight )
>
>        if content != None:
>            return QVariant( content )
>        else:
>            # default choice
>            return QVariant()
>
>
>
>
>    def index( self, row, column, parent_index ):
>
>        parent = self.nodeFromIndex( parent_index )
>        if parent == "coco":
>            child = self.children_offirstline[0]
>        else:
>            child = self.children[ row ]
>        index = self.createIndex( row
>                , column
>                , child )
>
>        return index
>
>
>
>    def nodeFromIndex( self, index ):
>
>        if index.isValid():
>            node = index.internalPointer()
>            return node
>        else:
>            node = self.root
>            return node
>
>
>    def parent( self, child_index ):
>
>        node = self.nodeFromIndex( child_index )
>        if node == "coucou":
>            index = self.createIndex( 0, 0, self.root )
>            return index
>        else:
>            return QModelIndex()
>
>
>    def allIndex( self ):
>
>        yield QModelIndex()
>        index = self.createIndex( 0, 0, self.children[0] )
>        yield index
>        index = self.createIndex( 0, 0, self.children_offirstline[0] )
>        yield index
>
>
>
> class TreeROWidget( QWidget ):
>
>
>
>    def __init__( self
>            , TreeROModel_
>            , title = None
>            , parent = None ):
>
>        super( TreeROWidget, self ).__init__( parent )
>
>        # central tree view
>        self.view = QTreeView( parent )
>        self.view.setSelectionBehavior( QTreeView.SelectItems )
>
>        # central tree model
>        self.model = TreeROModel_
>        self.proxyModel = CustomProxyModel()
>        self.proxyModel.setSourceModel( self.model )
>
>        self.view.setModel( self.proxyModel )
>        self.view.setAlternatingRowColors( True )
>
>
>        self.connect( self.view, SIGNAL( "clicked(QModelIndex)" )
>                , self.cellClicked )
>
>        # layout
>        vboxlayout = QVBoxLayout()
>        hboxlayout = QHBoxLayout()
>        vboxlayout.addLayout( hboxlayout )
>        vboxlayout.addWidget( self.view )
>        self.setLayout( vboxlayout )
>
>        self.show()
>
>
>    def cellClicked( self, qmodelindex ):
>
>        if qmodelindex.isValid():
>            qmodelindex = self.proxyModel.mapToSource( qmodelindex )
>            print qmodelindex.internalPointer()
>
>
>
> class TreeWidget( TreeROWidget ):
>
>    def __init__( self
>            , TreeROModel_
>            , title = None
>            , parent = None ):
>
>        super( TreeWidget, self ).__init__( parent = parent
>                , TreeROModel_ = TreeROModel_
>                , title = title )
>
>
>
> if __name__ == "__main__":
>
>    def add_col():
>
>        for index in widget.model.allIndex():
>            print index, index.internalPointer()
>            widget.model.beginInsertColumns( index, 2, 2 )
>            widget.model.endInsertColumns()
>
>    def add_row():
>
>        index = QModelIndex()
>        l = len( widget.model.children )
>        widget.model.beginInsertRows( index, l, l )
>        widget.model.children.append( "toto %i" % l )
>        print widget.model.children
>        widget.model.endInsertRows()
>
>    app = QApplication( sys.argv )
>    dialog = QDialog( )
>    dialog.resize( 750, 550 )
>
>    widget = TreeWidget( TreeROModel() )
>
>    vboxlayout = QVBoxLayout( dialog )
>    vboxlayout.addWidget( widget )
>    dialog.setLayout( vboxlayout )
>    dialog.show()
>    widget.view.resizeColumnToContents( 0 )
>    widget.view.resizeColumnToContents( 1 )
>
>    pushbutton1 = QPushButton( "Add column in line 1" )
>    pushbutton2 = QPushButton( "Add row" )
>    vboxlayout.addWidget( pushbutton1 )
>    vboxlayout.addWidget( pushbutton2 )
>
>    QObject.connect( pushbutton1, SIGNAL( "clicked()" )
>            , add_col )
>    QObject.connect( pushbutton2, SIGNAL( "clicked()" )
>            , add_row )
>
>    app.exec_()
>
>
>
> --
> python -c "print ''.join([chr(154 - ord(c)) for c in '*9(9&(18%.\
> 9&1+,\'Z4(55l4('])"
>
> "When a distinguished but elderly scientist states that something is
> possible, he is almost certainly right. When he states that something is
> impossible, he is very probably wrong." (first law of AC Clarke)
>
>
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://www.riverbankcomputing.com/pipermail/pyqt/attachments/20090515/b8d54cbf/attachment.html


More information about the PyQt mailing list