[PyQt] Qt or PyQt problem?

Darren Dale dsdale24 at gmail.com
Wed Jun 3 19:51:30 BST 2009


On Wed, Jun 3, 2009 at 2:40 PM, Darren Dale <dsdale24 at gmail.com> wrote:

> On Wed, Jun 3, 2009 at 2:20 PM, Darren Dale <dsdale24 at gmail.com> wrote:
>
>> On Wed, Jun 3, 2009 at 12:08 PM, Phil Thompson <
>> phil at riverbankcomputing.com> wrote:
>>
>>> On Wed, 03 Jun 2009 17:37:29 +0200, "V. Armando Solé" <sole at esrf.fr>
>>> wrote:
>>> > Hello,
>>> >
>>> > The problem can be solved as shown below.
>>> >
>>> > It seems the linux 32 bit implementation gets confused in
>>> > createIndex(row, column, a) when a is not an integer but a long. With
>>> > small values of a (10, 100, 1000),  the indexId() method returns the
>>> > supplied value.
>>> >
>>> > The solution is to call createIndex(row, column, a) with a being a
>>> > python object and not its id. The indexId() method can be masked with a
>>> > 32 bit mask if it returns a negative value. I have only found that
>>> > misbehavior under linux 32bit. Windows XP and linux 64-bit behave
>>> properly.
>>> >
>>> > Thanks for your time,
>>> >
>>> > Armando
>>> >
>>> > import PyQt4.Qt as qt
>>> > import random
>>> > import sys
>>> >
>>> > mask = 0xFFFFFFFF
>>> >
>>> > class Model(qt.QAbstractItemModel):
>>> >   def index(self, row, column, parent):
>>> >       a=[random.random()]
>>> >       index =  self.createIndex(row, column, a)
>>> >       print "Next two values should be the same"
>>> >       returned = index.internalId()
>>> >       if returned < 0:
>>> >           returned = returned & mask
>>> >       print "indexInternalId = ", returned
>>> >       print "id(a) = ", id(a)
>>> >       print "Forcing to be the same with a 32 bit mask"
>>> >       print "indexInternalId = ", index.internalId() & mask
>>> >       print "id(a) = ", id(a) & mask
>>> >       return index
>>> >
>>> > if __name__ == "__main__":
>>> >   app = qt.QApplication([])
>>> >   w = Model()
>>> >   w.index(0,0,None)
>>>
>>> Could you see if the problem goes away if you change
>>> qabstractitemmodel.sip
>>> so that...
>>>
>>>    QModelIndex createIndex(int arow, int acolumn, int aid) const;
>>>
>>> ...is replaced by...
>>>
>>>    QModelIndex createIndex(int arow, int acolumn, quint32 aid) const;
>>>
>>
>> I applied this change to the 20090601 snapshot. Executive summary: when I
>> check different data types, I can still find places where the two id's do
>> not agree. I find disagreement with the mask applied and without:
>>
>> When I run the script I posted, I get output like:
>>
>> Next two values should be the same
>> indexInternalId =  1849945336
>> id(a) =  139691366280440
>>
>> If I apply Armando's mask, I get:
>>
>> Next two values should be the same
>> indexInternalId =  12719168
>> id(a) =  12719168
>>
>> If I remove the mask and instead do "a=[numpy.uint32(random.random())]", I
>> get ouput like:
>>
>> Next two values should be the same
>> indexInternalId =  12719168
>> id(a) =  12719168
>>
>> Still without the mask, if I do "a=[numpy.int64(random.random())]":
>>
>> Next two values should be the same
>> indexInternalId =  12719168
>> id(a) =  12719168
>>
>> And finally, with Armando's mask and with
>> "a=[numpy.int64(random.random())]":
>>
>> Next two values should be the same
>> indexInternalId =  110072896
>> id(a) =  139754050917440
>>
>
> There was a bug report, it has been marked "won't fix":
> http://www.qtsoftware.com/developer/task-tracker/index_html?method=entry&id=204226
>

One last point, however: I think Armando's suggestion of passing the object,
and not the object's id(), coupled with Phil's patch, is the right solution:

import PyQt4.Qt as qt

import random
import sys

import numpy

class Model(qt.QAbstractItemModel):
  def index(self, row, column, parent):
      a=(random.random(),)
      index =  self.createIndex(row, column, a)
      print "Next two values should be the same"
      print "indexInternalId = ", index.internalId()
      print "id(a) = ", id(a)

      a=(numpy.uint32(random.random()),)
      index =  self.createIndex(row, column, a)
      print "Next two values should be the same"
      print "indexInternalId = ", index.internalId()
      print "id(a) = ", id(a)

      a=(numpy.uint64(random.random()),)
      index =  self.createIndex(row, column, a)
      print "Next two values should be the same"
      print "indexInternalId = ", index.internalId()
      print "id(a) = ", id(a)

      return index

if __name__ == "__main__":
  app = qt.QApplication([])
  w = Model()
  w.index(0,0,None)


With Phil's patch, running this script on 64-bit linux yields:

Next two values should be the same
indexInternalId =  8744016
id(a) =  8744016
Next two values should be the same
indexInternalId =  8744080
id(a) =  8744080
Next two values should be the same
indexInternalId =  8744016
id(a) =  8744016

Darren
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://www.riverbankcomputing.com/pipermail/pyqt/attachments/20090603/fe9501b6/attachment-0001.html


More information about the PyQt mailing list