[PyKDE] Weird problem with a QTabWidget subclass that overrides insertTab

Matthew Scott gmane at goldenspud.com
Sun Jul 18 13:57:00 BST 2004


Hi all,

I am diving head-first into PyQt again.  This will be the third time in 
as many years, and the third time I am enjoying the experience :-)  This 
is the first time I'm in a spot where I'm doing stuff that doesn't 
involve any QT Designer usage though, and the first time I'm subclassing 
built-in widgets extensively.

My problem is that of overriding methods in subclasses of Qt widgets. 
Say you have a class Y which is a subclass of X and overrides the method 
z.  You want to call the z method from the X class as part of the 
overridden method.  The following code will print "abcdef":

class X:
   def z(self):
     return 'abc'
class Y(X):
   def z(self):
      return X.z(self) + 'def'
print Y().z()

So far, so elementary.

Now we get to the tricky part.  You'd expect the following code to print 
this:

addTab(somethingElse='bar')
   calling self.insertTab
insertTab(somethingElse='bar')
insertTab done

But it doesn't.  Instead it prints this:

addTab(somethingElse='bar')
   calling self.insertTab
insertTab(somethingElse='bar')
insertTab(somethingElse='foo')
insertTab done
insertTab done

Here is the offending code, blank lines stripped out for brevity:

import sys
import qt
class TabWidget(qt.QTabWidget):
     def addTab(self, widget, label, somethingElse='foo'):
         print 'addTab(somethingElse=%r)' % somethingElse
         print '  calling self.insertTab'
         self.insertTab(widget, label, somethingElse=somethingElse)
     def insertTab(self, widget, label, index=-1, somethingElse='foo'):
         print 'insertTab(somethingElse=%r)' % somethingElse
         qt.QTabWidget.insertTab(self, widget, label, index)
         print 'insertTab done'
class MainWindow(qt.QMainWindow):
     def __init__(self, parent=None, name=None):
         qt.QMainWindow.__init__(self, parent, name)
         self._setup()
     def _setup(self):
         self.tabWidget = TabWidget(self)
         self.setCentralWidget(self.tabWidget)
         self.someWidget = qt.QWidget(self.tabWidget)
         self.tabWidget.addTab(self.someWidget, 'some widget',
                               somethingElse='bar')
class App(qt.QApplication):
     def __init__(self):
         qt.QApplication.__init__(self, sys.argv)
         self._setup()
     def _setup(self):
         self.mainWindow = MainWindow()
         self.setMainWidget(self.mainWindow)
         self.mainWindow.show()
if __name__ == '__main__':
     app = App()
     app.exec_loop()

The problem is in TabWidget.insertTab, since it tries to call the 
superclass's insertTab method.  But it doesn't quite do that.  It 
instead ends up calling ITSELF again before it finally calls the 
superclass's method.  By doing so, it loses the custom 'somethingElse' 
that was set, which in my real-world code means that the overridden 
method becomes somewhat useless :)

FYI, if you rename insertTab to insertTab2, and have addTab call that 
instead, and have insertTab2 still call superclass's insertTab method, 
problem "solved" and you get the expected output.

But this seems weird, and a bit silly in my opinion.  I really want to 
have my QTabWidget subclass have the same API as QTabWidget itself, with 
just a few minor options added on.

Has anyone else run into this problem who can offer a solution?

Or perhaps, does anyone have a clear idea of why the above code is 
exhibiting this behavior and what a "better" way of doing it would be? :-)


Thanks very much,

- Matthew


FYI - I am running Debian unstable with Python 2.3.4, and version 3.11-4 
of the python2.3-qt3 package installed.  I'd be curious to know if the 
code given above acts differently on other systems or versions of PyQt.




More information about the PyQt mailing list