On Sat, 2 Jan 2010 15:38:00 +0300, z <[email protected]> wrote: > 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?
No. Phil _______________________________________________ PyQt mailing list [email protected] http://www.riverbankcomputing.com/mailman/listinfo/pyqt
