Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct
Performance issue on real-time wave plot into QImage and update() to QWidget
nice to see you guys.
I am developing a real-time ECG signal plotting on x86.
The brief requirement is to draw the ECG signal as a real-time wave:
- Draws the 500 HZ ECG signal sample into a backend QImage via QPainter in a sub-thread (in order to async with UI thread so that it will no impact interaction or even impacted by UI interactoin, at each 25 msec (buffered data);
- After QImage is drawn, call QWidget::update() to notify UI thread, then QWidget (actually the derived QWidget class) simply draws the QImage on it to show the plotted ECG wave data.
But, the issue is, the cpu cost is rather high as, nearly 50%. (dual-core i3)
I tried to comment out the paintEvent override of the QWidget derived class to not perform the UI thread rendering of QImage, only let the sub-thread to plot the data on QImage silently, and found that the cost is still about 50%.
I tried QWindow and QBackingstore in a sub-thread without using QWidget::update(), it works fine, but it is not acceptable because QWindow cause another native window to be created, which breaks my visual effect made by alien QWidget ( or GrahpicsItem).
Seems that, the QWidget::update() in a 40HZ rate is the bottleneck?
Can any one give me some idea on the rule of QWdiget::udpate() ? Shouldn't it be used in that high frequency? and, is there any other way to render onto the QWidget surface exception for calling update() ?
Hi and welcome to devnet,
Not a direct response to your question, but since it's seems to be an intensive painting application, did you consider using opengl for your drawing ?
It would also be good to give the Qt version and OS you are running your application on
Hi SG, thanks very much for you concentration.
The Qt version is 5.0.0, Windows XP professional.
We tried OpenGL but seems OpenGL can not partially update the drawing surface, and we need to re-paint the whole screen each 25 msec, it still has some performance issue.
But the key we don't try opengl much is that we need to utilize QT's annimation, effect, z-order of alien widget.
We call QWidget::update() every 25 msec, that is of 40HZ, and by compare with QWindow & QBackingstore, we assume that QPainter drawing itself is not so cost.
We also tried to reduce the call to update(), to 1HZ, and the performance is very nice.
8majkel8 last edited by
do not draw plot into QImage. You can use "qwt":http://qwt.sourceforge.net/, QGraphicsView or custom QWidget::paintEvent to draw it directly.
Using buffer object you will be able to partially update OpenGL scene.
Thank you very much.
I tried writing another simple program to do the testing, seems update() with 40HZ has no problem. There must be some other points that affect my program's performance.
BTW, I can not avoid to use QImage to backup all the rendered wave plots because a system generated update() with a larger region causes the already drawed plots be erased, without a QImage as a secondary buffer, I can not re-paint the whole plots back to the widget or graphics item.
why not putting each plot into a separate widget?
I mean subclass QWidget and do your painting in there in the paintEvent() handler.