PyQt5 QTimer 10ms is not accurate with QEventLoop and qasync in GUI APP
-
Hi,
Pyqt5+python3.9
I have a weird behaviour with QTimer in PyQT5 when I try to measure frames and frequency. If you set a timer with 10ms = 1 / 100 every signal message gives the time every time. It works with the following snippet but then with another app with QEventLoop/qasync has a big latency.
First of all I have this sample code snippet:
from PyQt5 import QtWidgets from PyQt5.QtWidgets import QApplication, QMainWindow from PyQt5 import QtCore from PyQt5.QtCore import QElapsedTimer import sys count = 0 def display(): global t1, count with open("output.txt", "a") as f: f.writelines(str(t1.elapsed() / 1000.) + " " + str(count) + "\n") count = count + 1 app = QApplication([]) win = QMainWindow() win.setGeometry(400,400,300,300) win.setWindowTitle("CodersLegacy") t1 = QElapsedTimer() timer = QtCore.QTimer() timer.timeout.connect(display) t1.start() timer.start(10) count = 0 sys.exit(app.exec_())
It's pretty simple, write every time elapsed time and frame count. A sample output (tail of file):
20.799 2079 20.809 2080 20.82 2081 20.83 2082
You can divide 2082 / 20.83 = 100 (aprox.) then is the real frequency 10ms = 1/100 Good! But...
... I have a GUI PyQt5 app with EventLoop and Qasync. I put the main of the app:
def main(): global splash QApplication.setAttribute(Qt.AA_UseDesktopOpenGL) QApplication.processEvents() app = QApplication([]) w = MainWindow() w.resize(1600, 900) w.show() try: loop = qasync.QEventLoop(app) asyncio.set_event_loop(loop) except asyncio.InvalidStateError as e: print(e + " Error en Qasync") with loop: loop.run_forever() if __name__ == "__main__": main()
And QMainWindow class (a snippet with important code), I have the timer signal:
class MainWindow(QMainWindow): ... self.timer = QTimer() self.timer.timeout.connect(self.timerFile) self.timer.start(10) def timerFile(self): global timer_count with open(current_file, "a") as f: f.writelines("TIME: " + str(t1.elapsed() / 1000.) + " " + str(timer_count) + "\n") timer_count = timer_count + 1
And the output file:
TIME: 4.357 228
So, total frequency is 228 / 4.357 = 52.32 = 1 / 52.32
It's double time. And I have tried timestamps, PreciseTimer, but always I have the same behaviour.
I don't know what happens with timer signals in PyQt5 with EventLoop or/and qasync. Someone could send me some tips to resolve this or investigate the solution.
I appreciate your help Kind Regards
-
Hi and welcome to devnet,
What happens if you run your application without qasync ?
Shouldn't you useloop.exec()
?