I'm developing a PyQt6 app that plots data from a measurement instrument and something else related to user input, and I'm experiencing outstanding lags when I run it on Windows vs on the WSL (Windows Subsystem for Linux) of the same machine! Here are a few details about the Qt objects I'm using there:
matplotlib.backends.backend_qtagg.FigureCanvas
.QtCore.QTimer
with the smallest possible interval of 1ms
(according to docs) to get data from the measurement instrument and update the plot with it.QTimer
is used to update all of them.Could it be the QTimer
usage doesn't fit this usecase? Perhaps I should use a QThread
? Or a QThread
per channel? I was also thinking about switching to pyqtgraph
....
Which ever change from the above I'll apply to my code, it will improve the performance of it on all platforms, so in either way, it would be very interesting to get a clue why running it natively on Windows is so much slower.
Adding a print
statement in the timer's timeout function, would show you that the GUI is not exactly stuck, since the timeout function keeps on printing even when the GUI seems to be stuck. This is a sign that the Qt event loop doesn't manage to handle the events between the timer's timeout function calls.
On different platforms, the event loop is implemented differently, and also CPU / system load may impact, so in such low-interval timers, it is safe to process events manually. Here's a minimal working example:
import time
from PyQt6 import (
QtWidgets,
QtCore,
)
class ApplicationWindow(QtWidgets.QMainWindow):
def __init__(self):
super().__init__()
self._main = QtWidgets.QLabel()
self.setCentralWidget(self._main)
self._timer = QtCore.QTimer()
self._timer.timeout.connect(self.updateTimerLabel)
self._timer.start()
def updateTimerLabel(self):
self._main.setText("Time now is {}".format(time.time()))
# This is the important part!
qapp.processEvents()
qapp = QtWidgets.QApplication([])
app = ApplicationWindow()
app.show()
app.activateWindow()
app.raise_()
qapp.exec()
See also: