[PyQt] Overriding (hooking) an event() function: QWidget vs QGraphicsWidget

z zoomer.gm at gmail.com
Sat Jan 2 10:15:52 GMT 2010


Hello everybody, and happy new year!
to the point:
In python it is possible to override some method of an instance,
assigning to a "instance.methodname" a new value (which must be
callabe with the same number of arguments, to be useful)
For example i'd like to intercept events, coming to some widget,
having this widget instance. It is easy to achieve, if i define this
widget's class myself, and therefore can redefine event() method in
class definiion. But suppose, that i just providing an interface for
using by other parties. One, who using it only give me an instance,
which class definition i can not control.
This is an example program, which defines a hook function, and
replaces instance's original event() method with it (for the start we
will see how it works for QGraphicsWidget):
###########################
from PyQt4 import QtGui, QtCore

app = QtGui.QApplication(sys.argv)

# suppose this class is defined somewhere else
class Target(QtGui.QGraphicsWidget):
    def __init__(self):
        QtGui.QGraphicsWidget.__init__(self)

target = Target()
target.show()

eventOrig = target.event

# intercept function, which just prints incoming event type, and
passes further processing to original event()
def eventHook(ev):
    print 'HOOK', ev.type()
    return eventOrig(ev)

target.event = eventHook

# Let's trigger an event()
QtGui.QApplication.postEvent(target, QtCore.QEvent(QtCore.QEvent.LayoutRequest))
target.resize(200,200)

sys.exit(app.exec_())
############################

Of course, it is not fully complete and sane code, but it
demonstrates, that this approach works fine. This is console output of
this program:
###########
HOOK 181
HOOK 76
############
(181 is QEvent.GraphicsSceneResize, and 76 is layoutrequest ) So it
works for QGraphicsWidget.
But it does not work for QWidget. i.e. if the class is defined as:
############
class Target(QtGui.QWidget):
   def __init__(self):
       QtGui.QWidget.__init__(self)
#############
Nothing appears on output at all. But the program runs flawlessly,
(and shows main window, containing this widget)

So the question is: what's the difference? Why it works for
QGraphicsWidget, but not QWidget? Is it some peculiarities of Qt event
processing? Or is it PyQt? Or is it my system config or installed
software gone wrong?

P.S: running system config:
- linux x86_64
- python 2.6
- PyQt 4.6.2
- Qt 4.6



More information about the PyQt mailing list