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 _______________________________________________ PyQt mailing list [email protected] http://www.riverbankcomputing.com/mailman/listinfo/pyqt
