Reputation: 1921
In our PyQt application we want to time the duration of all Qt Events. Only in a special performance monitoring mode. Previously I subclassed QApplication and overrode the notify()
method and that worked great. I wrote the data in chrome://tracing
format and it was super helpful.
However when our application is run inside Jupyter there is a pre-existing QApplication instance. So I can't think of how to make it use my subclass.
Instead I tried monkey patching below, but my notify()
is never called. I suspect notify()
is a wrapped C++ method and it can't be monkey patched?
def monkey_patch_event_timing(app: QApplication):
original_notify = app.notify
def notify_with_timing(self, receiver, event):
timer_name = _get_timer_name(receiver, event)
# Time the event while we handle it.
with perf.perf_timer(timer_name, "qt_event"):
return original_notify(receiver, event)
bound_notify = MethodType(notify_with_timing, app)
# Check if we are already patched first.
if not hasattr(app, '_myproject_event_timing'):
print("Enabling Qt Event timing...")
app.notify = bound_notify
app._myproject_event_timing = True
Is there a way to monkey patch QApplication.notify
or otherwise insert code somewhere that can time every Qt Event?
Upvotes: 2
Views: 386
Reputation: 244202
A possible solution is to remove the old QApplication with the help of sip and create a new one:
def monkey_patch_event_timing():
app = QApplication.instance()
if app is not None:
import sip
sip.delete(app)
class MyApplication(QApplication):
def notify(self, receiver, event):
ret = QApplication.notify(self, receiver, event)
print(ret, receiver, event)
return ret
app = MyApplication([])
return app
Upvotes: 2