[PyQt] Bugs galore in QAbstractTableModel???

Ian hobson42 at gmail.com
Sat Nov 27 23:26:42 GMT 2010


On 27/11/2010 23:00, Andreas Pakulat wrote:
> 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:
>
> https://projects.kde.org/projects/extragear/kdevelop/kdevplatform/repository/revisions/master/show/tests
>
>>      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
> parent.isValid().
>
>>      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
> critical.
>
>>      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 ==
> DisplayRole.
>
>>      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.
>
> Andreas
>
Thanks Andreas,
The hint about testing role in data removed the (uncheckable) check boxes,
and calling  resizeColumnsToContents() now sets the columns to the width 
(but not the window).

However, setting the number of fields to 5, still removes the headers.

Regards

Ian





More information about the PyQt mailing list