我如何猴子修补 PyQT 的 QApplication.notify() 来计时事件

How can I monkey patch PyQT's QApplication.notify() to time events

在我们的 PyQt 应用程序中,我们想要对所有 Qt 事件的持续时间进行计时。仅在特殊的性能监控模式下。以前我将 QApplication 子类化并覆盖 notify() 方法并且效果很好。我以 chrome://tracing 格式编写了数据,它非常有用。

然而,当我们的应用程序 运行 在 Jupyter 中时,有一个预先存在的 QApplication 实例。所以我想不出如何让它使用我的子类。

相反,我尝试了下面的猴子补丁,但我的 notify() 从未被调用过。我怀疑 notify() 是一个包装的 C++ 方法,它不能被猴子修补?

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

有没有办法猴子补丁 QApplication.notify 或以其他方式在某处插入代码来为每个 Qt 事件计时?

一个可能的解决方案是在 sip 的帮助下删除旧的 QApplication 并创建一个新的:

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