[PyQt] Bugs galore in QAbstractTableModel???

Andreas Pakulat apaku at gmx.de
Sat Nov 27 23:00:18 GMT 2010

On 27.11.10 21:27:55, Ian wrote:
> On 27/11/2010 21:07, Andreas Pakulat wrote:
> >On 27.11.10 20:54:01, Ian wrote:
> >>I am trying to use QAbstractTableModel and I am having more than
> >>some difficulty.
> >>
> >>If I return the correct number to columnCount I get no headers. If I
> >>return a number that is too big, I get headers, but the model is
> >>asked for headers and data for columns that don't exist!
> >>
> >>Everywhere I return a String in the data()  routine, this is
> >>displayed with a check box - even if I cast it to QVariant.
> >There's a C++ class called QModelText which sanity-checks models, I
> >believe that an older version was converted to python and is included in
> >PyQt4. Run it on your model, fix the problems and see wether that helps.
> >
> Thanks for your reply Andreas,
> I can find nothing about QModelText, and QModelTest appears to have

Sorry, typo :)

> a few bug reports and
> nowhere to download it and no instructions as to how to run it, and
> is not on my hard disks.

Ah, right I totally forgot that its been 'dropped' into /dev/null by
Nokia at the point where qtlabs was closed. Unfortunately Nokia doesn't
provide it yet at some other place. There's a copy of the last svn
version of the C++ code here:


>     def rowCount(self, parent = None):
>         ''' return No of rows of data. parent is a QModelIndex '''
>         return len(self.view)

This is wrong, even for table models you have to take care to return the
right number of rows depending on the parent. That means if your model
gets asked for the rowCount with a valid parent, you want to return 0
(as you don't have childs under any of your rows). So check for

>     def columnCount(self, parent = None):
>         ''' return number of columns. parent = QModelIndex()
>            id, name, cubref, address, town, contacts
>         '''
>         return 6

Basically the same here as above, though I think this is not quite as

>     def data(self, index, role):
>         ''' return data as QVariant at index.row and index.col '''
>         key = self.view.rows[index.row()].key
>         idx = index.column()
>         if  idx < len(key):
>             val = key[idx]
>             if val is None:
>                 return QVariant()
>             return QVariant(val)
>         return QVariant()

This can potentially throw exceptions because index may be invalid in
which case index.row() is return -1. So again check the index for
validity. Also you should only return data for role's you really want to
handle and return QVariant() for anything else, i.e. check for role ==

>     def headerData(self, col, orientation, role):
>         ''' return the header data '''
>         if orientation == Qt.Horizontal:
>             tab = ['Name','Cub Ref','Street','Town','Contacts']
>             if col < len(tab):
>                 return tab[col]
>         return None

I'm not sure about PyQt's constraints on this, but its common to return
a dummy QVariant from these functions. Oh and again the role-thing from
above applies.

And yes all of this is not documented in Qt's API docs, though its
visible in the example models that Qt ships. Maybe there's already a
bugreport open for an improvement.


You fill a much-needed gap.

More information about the PyQt mailing list