Reputation: 1921
This stack overflow answer seems to provide a really clean way to monitor the duration of all Qt events in C++. I'm interested in doing something similar in Python for a PyQt5 application.
The high level goal is to have profiling we can optionally enable to get hard numbers for what is making the application feel slow. How long did the paint take? How long did that mouse click take? Any ideas?
Upvotes: 1
Views: 2027
Reputation: 21
Reusing the same QElapsedTimer
instance is a bad idea because notify
may be called inside of the method itself. In that case start
will be called again, which results in incorrect shorter time measurements. Also, I would expect that to cause problems if you are using threads. To avoid all that I would make use of local variables and use time.monotonic
instead of QElapsedTimer
to measure the time difference.
I ran occasionally into exceptions when I tried calling receiver.objectName()
after notify()
. Qt complained that receiver
had been deleted.
This works for me:
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()
Upvotes: 2
Reputation: 24430
You could just pythonify the C++ code in the linked answer:
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()
Upvotes: 3