2010/1/2 Phil Thompson <[email protected]>: > On Sat, 2 Jan 2010 13:15:52 +0300, z <[email protected]> wrote: >> 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 > > PyQt caches lookups for Python reimplementations of methods. Monkey > patching will only work if you patch a method before it is looked up for > the first time. Your example will work for QWidget if you move the call to > show() after you patch it. > > Phil >
Oh, thanks for the explanation. This raises another question: is there any way to flush this PyQt cache from inside my program to force it use new monkey-patched version instead of cached? _______________________________________________ PyQt mailing list [email protected] http://www.riverbankcomputing.com/mailman/listinfo/pyqt
