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