如何分析 PyQt 应用程序中的事件?

How can I profile events in a PyQt application?

stack overflow answer 似乎提供了一种非常干净的方法来监视 C++ 中所有 Qt 事件的持续时间。我有兴趣在 Python 中为 PyQt5 应用程序做类似的事情。

高级目标是进行分析,我们可以选择启用该分析以获取使应用程序感觉缓慢的确切数字。油漆用了多长时间?鼠标点击需要多长时间?有什么想法吗?

您可以将链接答案中的 C++ 代码 python 化:

from PyQt5.QtCore import QElapsedTimer
from PyQt5.QtWidgets import QApplication, QPushButton

class MyApplication(QApplication):

    t = QElapsedTimer()

    def notify(self, receiver, event):
        self.t.start()
        ret = QApplication.notify(self, receiver, event)
        if(self.t.elapsed() > 10):
            print(f"processing event type {event.type()} for object {receiver.objectName()} " 
                  f"took {self.t.elapsed()}ms")
        return ret


if __name__ == "__main__":
    app = MyApplication([])
    ....
    app.exec()

重用同一个 QElapsedTimer 实例不是一个好主意,因为 notify 可能会在方法本身内部被调用。在那种情况下 start 将被再次调用,这会导致不正确的更短时间测量。另外,如果您使用线程,我希望这会导致问题。为了避免所有这些,我会使用局部变量并使用 time.monotonic 而不是 QElapsedTimer 来测量时差。

当我尝试在 notify() 之后调用 receiver.objectName() 时,我 运行 偶尔会出现异常。 Qt 抱怨 receiver 已被删除。

这对我有用:

import time
from PyQt5.QtWidgets import QApplication, QPushButton

class MyApplication(QApplication):

    def notify(self, receiver, event):
        eventType = event.type()
        receiverName = receiver.objectName()
        start = time.monotonic()
        ret = QApplication.notify(self, receiver, event)
        end = time.montonic()
        elapsedMSec = (end - start) * 1000
        if(elapsedMSec > 10):
            print(f"processing event type {eventType} for object {receiverName} took {elapsedMSec} msec")
        return ret


if __name__ == "__main__":
    app = MyApplication([])
    ....
    app.exec()