[PyKDE] QScrollView.viewport() wrapped up with wrong type

Johannes Sixt Johannes.Sixt at telecom.at
Sun Nov 7 14:34:54 GMT 1999


I came across the following problem with QScrollView.viewport()

The script below produces an error:

TypeError: Invalid argument types to QPainter()

A little background: The QScrollView widget has a child widget that can be
retrieved with QScrollView::viewport(). Also, Qt installs the QScrollView
widget as an event filter for that child widget (hence, I don't need to do that
myself in the script). Now (referring to the script below) MyView.eventFilter
is called for every event that goes to the viewport. In particular,
QScrollView::eventfilter calls QScrollView::viewportMousePressEvent (or any
override if it exists). (All this is pretty normal Qt/QScrollView, nothing
special.)

The problem is now the following: When PyQt calls MyView.eventFilter, it has to
wrap up the object that it gets passed in, which happens to be the viewport().
But it gets it as a pointer to a QObject, not to a QWidget. Hence PyQt wraps it
up as a QObject. Later in the call chain, in MyView.viewportMousePressEvent(),
when the line should be painted, the script retrieves self.viewport(). But
since the object is already wrapped up, it only get a QObject instead of a
QWidget -- type error.

Is there a way around this?
Phil, can sip "upgrade" the object in such a situation?

-- Hannes

#!/usr/bin/env python
import qt,sys

class MyView(qt.QScrollView):
        def __init__(self,*args):
                apply(qt.QScrollView.__init__, (self,) + args)

        # paint a line when the mouse is pressed
        def viewportMousePressEvent(self,ev):
                # error happens in the next line
                p = qt.QPainter(self.viewport())
                p.drawLine(10,20, 150,180)

        # if you disable the eventFilter (by renaming it) everything's ok     
        def eventFilter(self,ob,ev):
                return qt.QScrollView.eventFilter(self,ob,ev)

app = qt.QApplication(sys.argv)
w = MyView()
app.setMainWidget(w)
w.show()
app.exec_loop()

#------end of script




More information about the PyQt mailing list