[PyKDE] subclassing in pyqt

Boudewijn Rempt bsarempt at rempt.xs4all.nl
Sat Dec 23 09:51:37 GMT 2000


On Fri, 22 Dec 2000, David Berner wrote:

> i found a problem while subclassing pyqt-classes in python.
> 
> e.g.
> 
> >>> class Mylistview(QListView):
> >>>   (...)
> >>>
> >>> class Mylistitem(QListViewItem):
> >>>   def __init__(self, parent, name, myvar):
> >>>     apply(QListViewItem.__init__,(self,parent,name)
> >>>     self.MyVar = myvar
> >>>     (...)
> >>>
> >>> a = Mylistview(parent)
> >>> Mylistitem(a, "first item", 5)
> 
> the problem is, when i call a method of Mylistview which returns an item
> like:
> 
> >>> x = a.selectedItem()
> 
> since type(x) is not Mylistitem but QListViewItem, i can not access MyVar:
> 
> >>> print x.MyVar
> >>> (...) AttributeError: MyVar
> 
> AFAIK there are no type-conversions in python (in C a simple cast would do),
> so i see no way to solve this.
> 
> all comments are welcome,
> David
> 

This problem has been bugging me for some time, and I even have a set
of standard tests to determine whether a current version of PyQt works
or not - in the past there has been a version where it was impossible
to get at the subclass.

However, with current versions this is not a problem. The issue
is caused by the fact that a Python subclass of a Qt class when
instatiated creates two objects: a Python object and a Qt C++
object.

All you have to do is to keep a reference in Python to your subclass: if
you let the Python reference to the object go out of scope, you lose your
Python class. Qt still keeps a reference to the Qt object, i.e. to the
QListViewItem, so that's what you'll get if you access it. Try the
attached two scripts and see the essential difference in output:

boud at calcifer:~/src/python/prj/test/inherit > python inherit.py
<__main__.myListViewItem instance at 0x8242e3c>
<__main__.myListViewItem instance at 0x8242e3c>
slotHook

boud at calcifer:~/src/python/prj/test/inherit > python inherit4.py
<qt.QListViewItem instance at 0x8320b04>
Traceback (most recent call last):
  File "inherit4.py", line 39, in slotOpenFile
    item.slotHook()
AttributeError: slotHook

Boudewijn Rempt
-------------- next part --------------
#!/usr/bin/env python

import os
import sys

from qt import *

TRUE=1
FALSE=0

class myListViewItem(QListViewItem):
  
  def __init__(self, parent):
    QListViewItem.__init__(self, parent)

  def slotHook(self):
    print "slotHook"

class frmListView(QListView):
  """
    Self-displaying view of database data.
  """
  def __init__(self):  
    QListView.__init__(self)

    self.addColumn("a", 200)
    self.addColumn("b", 200)

    self.rows=[]
    lvi=myListViewItem(self)
    print lvi
    lvi.setText(0, "xxxxx")
    lvi.setText(1, "yyyyy")
    self.rows.append(lvi)
        
    self.connect(self, SIGNAL("doubleClicked ( QListViewItem * )")
                     , self.slotOpenFile
                     )
                     
  def slotOpenFile(self, item):
    print item
    self.currentItem().slotHook()

def main(argv):
  app=QApplication(sys.argv)
  win=frmListView()
  win.show()
  app.connect(app, SIGNAL('lastWindowClosed()'), app, SLOT('quit()'))
  return app.exec_loop()
 
if __name__=="__main__":
  main(sys.argv)
-------------- next part --------------
#!/usr/bin/env python

import os
import sys

from qt import *

TRUE=1
FALSE=0

class MyListViewItem(QListViewItem):
  
  def __init__(self, parent):
    QListViewItem.__init__(self, parent)

  def slotHook(self):
    print "slotHook"

class frmListView(QListView):
  """
    Self-displaying view of database data.
  """
  def __init__(self):
    QListView.__init__(self)

    self.addColumn("a", 200)
    self.addColumn("b", 200)

    lvi=MyListViewItem(self)
    lvi.setText(0, "xxxxx")
    lvi.setText(1, "yyyyy")
        
    self.connect(self, SIGNAL("doubleClicked ( QListViewItem * )")
                     , self.slotOpenFile
                     )
                     
  def slotOpenFile(self, item):
    print item
    item.slotHook()

def main(argv):
  app=QApplication(sys.argv)
  win=frmListView()
  win.show()
  app.connect(app, SIGNAL('lastWindowClosed()'), app, SLOT('quit()'))
  return app.exec_loop()
 
if __name__=="__main__":
  main(sys.argv)


More information about the PyQt mailing list