[PyKDE] QColorGroup

Johannes Sixt Johannes.Sixt at telecom.at
Wed Jan 19 21:56:03 GMT 2000


On Mon, 17 Jan 2000, Phil Thompson wrote:
>Johannes Sixt wrote:
>> 
>> a remedy for this situation would be that sipMapCppToSelf looks at the
>> requested type even if it finds already a Python object for the pointer. Then
>> it could wrap up the pointer a second time (for situations like the above where
>> the new type is unrelated to the old type) or it could "upgrade" (or
>> "downcast") the wrapper object to a derived class if the new class is derived
>> from the existing type. The latter would help in situations like the one that I
>> reported long ago under the subject "QScrollView.viewport() wrapped up with
>> wrong type".
>
>This is what I implemented in the patch - but I didn't do the
>upgrade/downcast. Can you give me a concrete example of where it would
>be needed - or remond me of the QScrollView.viewport() problem?

Ok, here is the problem (hold your breath):

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 gets a QObject instead of a
QWidget -- type error.

(That's it.)

Now, your patch has obviously fixed the problem. In particular, in this
situation I don't deem it necessary that the Python object is "upgraded" - it
doesn't hurt that there are 2 wrappers for the same C++ object. But keep this
example in mind, please.

-- 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