Drawing rectangles every 50 ms
-
@SGaist Thanks for your help.
What do you exactly mean with shuffling? I can imagine that you can draw them all at the beginning and only change the color for all rectangles. However, then you still would need to iterate over all the rectangles, changing their colors. Is that what you mean?
@HappyVisualizer i meant shuffling their positions.
-
@HappyVisualizer i meant shuffling their positions.
@SGaist Thanks for clarifying. So using a simple setpos() for each rectangle? Or do you suggest other functions / functionality? I'm really stuck at the moment..
-
No no, setPos is fine for that.
-
@SGaist Thanks a lot for your reply. It's been a while, but I did some testing and it seems that every time when calling setSceneRect(...), the paint function for all QGraphicsRectItems are being called. Is this indeed the case and instead of changing the coordinates of the scene every time (by going from [0, x] to [x, 2x] using setSceneRect(...)), is setPos(x,y) for each QGraphicsRectItem then faster and should I just change the positions of all these items in the scene, relative to the scene (and making sure 'old' rectangles are removed from the scene)?
And in that case, would QT be able to do this setPos() for 100,000 rectangles within 50 milliseconds? The idea behind the 100,000 rectangles is that we roughly 1.5h of data shown. Each rectangle has a width of 50 ms and each 50 ms, a new rectangle of data arrives. This pushes out the oldest rectangle, and would insert the newest rectangle. Thus, ((1.5 * 60 * 60 * 1000) / 50) = 108,000 objects where we need to apply setPos every 50 ms.
-
@SGaist Thanks a lot for your reply. It's been a while, but I did some testing and it seems that every time when calling setSceneRect(...), the paint function for all QGraphicsRectItems are being called. Is this indeed the case and instead of changing the coordinates of the scene every time (by going from [0, x] to [x, 2x] using setSceneRect(...)), is setPos(x,y) for each QGraphicsRectItem then faster and should I just change the positions of all these items in the scene, relative to the scene (and making sure 'old' rectangles are removed from the scene)?
And in that case, would QT be able to do this setPos() for 100,000 rectangles within 50 milliseconds? The idea behind the 100,000 rectangles is that we roughly 1.5h of data shown. Each rectangle has a width of 50 ms and each 50 ms, a new rectangle of data arrives. This pushes out the oldest rectangle, and would insert the newest rectangle. Thus, ((1.5 * 60 * 60 * 1000) / 50) = 108,000 objects where we need to apply setPos every 50 ms.
@HappyVisualizer
Yes to all that. Changing the whole scene rectangle will presumably repaint the whole scene, changing individual items redraws just them (and whatever they uncover). -
@HappyVisualizer
Yes to all that. Changing the whole scene rectangle will presumably repaint the whole scene, changing individual items redraws just them (and whatever they uncover).@JonB Thanks for your reply. I just tested this as follows:
for(auto& scene_item : scene()->items()) { if (scene_item->type() == SampleRectangle::Type) { SampleRectangle *rect_item = dynamic_cast<SampleRectangle*>( scene_item ); if (rect_item->get_time() < min_time) { scene()->removeItem(scene_item); } else { scene_item->setPos( width() * ((double)(rect_item->get_time() - min_time) / (double)(max_time - min_time)), 0); } } }The code checks if the rectangle item is outside the screen (by determining whether its time is lower than the current displayed minimum time) and else, we update the position of the rectangle in the scene. However, printing a counter in the paint() method of the QRectItem, I still see the counter incrementing, indicating the the paint() method is called everytime the setPos() function is called. I'm using Qt5 by the way. Do you know why paint() is still called for every setPos()?
-
@JonB Thanks for your reply. I just tested this as follows:
for(auto& scene_item : scene()->items()) { if (scene_item->type() == SampleRectangle::Type) { SampleRectangle *rect_item = dynamic_cast<SampleRectangle*>( scene_item ); if (rect_item->get_time() < min_time) { scene()->removeItem(scene_item); } else { scene_item->setPos( width() * ((double)(rect_item->get_time() - min_time) / (double)(max_time - min_time)), 0); } } }The code checks if the rectangle item is outside the screen (by determining whether its time is lower than the current displayed minimum time) and else, we update the position of the rectangle in the scene. However, printing a counter in the paint() method of the QRectItem, I still see the counter incrementing, indicating the the paint() method is called everytime the setPos() function is called. I'm using Qt5 by the way. Do you know why paint() is still called for every setPos()?
@HappyVisualizer
Whosepaint()is being called? Presumably you mean that of aQGraphicsItem, likeQGraphicsRectItem? So wouldn't you expect that to be called if you move the rectangle object? Something has to draw it at its new position, together with removing it from its old position.... -
@HappyVisualizer
Whosepaint()is being called? Presumably you mean that of aQGraphicsItem, likeQGraphicsRectItem? So wouldn't you expect that to be called if you move the rectangle object? Something has to draw it at its new position, together with removing it from its old position....@JonB Yes, that makes a lot of sense to me. But then I may have to rethink whether using a QGraphicsView and painting 100,000 custom QGraphicsRectItems every 50 ms is feasible. What do you think, would this be possible, or should I use something else like do the drawing with OpenGL?
The reason I went for custom QGraphicsRectItems is their HoverEvent and the capability of displaying tooltips. With OpenGL, I have to implement this myself (which seems to be a bit harder, but not impossible).
-
@JonB Yes, that makes a lot of sense to me. But then I may have to rethink whether using a QGraphicsView and painting 100,000 custom QGraphicsRectItems every 50 ms is feasible. What do you think, would this be possible, or should I use something else like do the drawing with OpenGL?
The reason I went for custom QGraphicsRectItems is their HoverEvent and the capability of displaying tooltips. With OpenGL, I have to implement this myself (which seems to be a bit harder, but not impossible).
@HappyVisualizer
Not my area I'm afraid. 100k per 50ms does sound like a lot to me. Don't forget that --- unless you explicitly tell scene/view to redraw each time you update a rectangle, which you should not do --- Qt will "buffer" all the updates. My understanding is that when it's that many it will probably end up redrawing the whole scene/view rather than each rectangle individually,It would not surprise me if OpenGL is better at speed, but you will have to await a more knowledgeable expert in that area than I.
-
Do you really need to show that many times at the same time ?
One thing you should take into account is how much data makes sense to be shown. Take for example video games, they do not render absolutely everything in every frame because that fine detail that is supposed to be 1000m away does not make sense to render in full details because you can't see them anyway.
-
Do you really need to show that many times at the same time ?
One thing you should take into account is how much data makes sense to be shown. Take for example video games, they do not render absolutely everything in every frame because that fine detail that is supposed to be 1000m away does not make sense to render in full details because you can't see them anyway.
@SGaist It's a good question. Another possibility would be to aggregate data. The idea is that it is possible to zoom in and out over timeframes, so for instance when we look at a timespan of 1 minute, we need 60 * 1000 / 50 = 1200 objects to be repainted every 50 ms, which seems to be attainable. Then, when we go to a larger timespan (say 1 hour), it would be possible to aggregate and let every block consist of (for instance) 1 second of data instead of 50 ms of data. Then, to draw the whole scene, we need to draw 60 * 60 * 1000 / (20 * 50) = 3600 objects, which is a lot less than previously proposed. Would you support this strategy?
-
Yes, that's the idea. Clustering data for more meaningful representation.
-
Great !
Then please mark the thread as solved using the "Topic Tools" button or the three dotted menu beside the answer you deem correct so that other forum users may know a solution has Ben found :-)