Hundreds of thousands of points
-
Hey all,
Is there a way to display 100,000 points? I tried the addellipse to my QGraphicsScene and they display but mouse interaction/zoom in and out is incredibly slow.
Dougie
-
@Doug-Hoppes
If you want that many dots, you certainly don't want them as any kind of graphics items! Cam't you draw them on the foreground or background? -
Hi and welcome to devnet,
Did you already look at the 40000 chips example ?
-
@JonB Not really. This is for a computer brain simulation. In reality, there may be up to 1.5 million points. In C++ on MFC platform, we just have the painter render the items as points. So, as the user zooms in and out, the points get rendered to the screen.
-
@Doug-Hoppes said in Hundreds of thousands of points:
In C++ on MFC platform, we just have the painter render the items as points.
Which is why I suggested adding gfx objects to the scene for each one is not the way to go....
-
@Doug-Hoppes said in Hundreds of thousands of points:
Still working out why the paint() method isn't being called
Share your code, we might be able to spot the issue.
However, you should rather approach it the "video game" way: only paint what is relevant at the zoom level you are. It does not make sense to draw all your points at level 0 if it just mean a blob for the user. As there's no reason to try to render the points that are "off camera" when you are zoomed at the max.
-
@SGaist Thanks! Yeah, also looking at various culling methods so that I can collapse X points into a representative point at different zoom levels (and the view area that the user has zoomed in on). Right now, just need to do some tests to see what the limit is on the number of points that renders effectively in the QGraphicsView.
In terms of the code, the basic design is that we're going to show markers as fonts when they are below 20,000 markers in the scene. Once they exceed, 20,000 markers, then I want to display them as points (There has been several requests for 2 million markers, etc).
// Constructor OverlayMarker::OverlayMarker(QGraphicsScene *pScene, AnnotationObject *pAnnotation): AnnotationOverlayItem(pScene, pAnnotation), m_fontwidth(200) { // The position level indicates how graphics items are placed over each // other. 0 is the bottom-most and infinity is the top-most m_positionLevel = 1650; m_pMarker = dynamic_cast<AnnotationMarker*>(m_pAnnotation); m_pMarkerItem = new QGraphicsTextItem(NULL); m_pMarkerItem->setZValue(m_positionLevel); m_pSelectionRect = new OverlayMarker::SelectionRect(m_pMarkerItem); m_pSelectionRect->setFlag(QGraphicsItem::ItemStacksBehindParent, true); m_pSelectionRect->setPen(QPen(QBrush(Qt::white), 2)); m_pSelectionRect->setVisible(false); // Provide the base class with the primary graphics item this->m_pGraphicsItem = m_pMarkerItem; // Define the marker font to be used m_markerFont.setFamily("Company Symbol"); m_markerFont.setPixelSize(m_fontwidth); setScaleAdjustment(3); m_pScene->addItem(m_pMarkerItem); } // Once the markers have been loaded into the system, the refreshDisplay() is immediately called. void OverlayMarker::refreshDisplay() { QGraphicsItem::prepareGeometryChange(); m_pScene->update(); } // The paint method is: void OverlayMarker::paint(QPainter* painter, const QStyleOptionGraphicsItem* option, QWidget* widget) { QPen linepen(Qt::red); linepen.setCapStyle(Qt::RoundCap); linepen.setWidth(30); painter->setRenderHint(QPainter::Antialiasing, true); painter->setPen(linepen); painter->drawPoint(m_pMarker->getPoint(0).x(), m_pMarker->getPoint(0).y()); }
-
-
Did you had the override keyword to the declaration of your paint method just to be sure it's properly declared ? (Looks like it)
As for the rest of your code, I must say it does not look right. You are doing scene handling within that item and it's not its role. If they are related to each other, they should be properly parented.
-
@SGaist I didn't add the "override" flag but it should have automatically overridden the ancestor class since it's the same signature. I also put a breakpoint in the ancestor paint() and it's not being called.
In terms of the architecture, the reason why it's designed this way is so that it can handle composite QGraphicItems. For example, in the future, we may want the OverlayMarkers to be QGraphicsTextItems for displaying the markers AND QGraphicsTextItems for displaying the marker names.
-
@Doug-Hoppes said in Hundreds of thousands of points:
I didn't add the "override" flag but it should have automatically overridden the ancestor class since it's the same signature.
Agreed, it should. But can't you now put
override
into the declaration so we'll know for sure? :) Especially since you say not being hit.I also put a breakpoint in the ancestor paint() and it's not being called.
Not sure where you mean you put a breakpoint on "ancestor".
-
@JonB Good point. When I put the override in the declaration, still wasn't called. I'm going to just try to force a paintevent() when I call the refresh and just see if it triggers the paint method. Also, I think that I'm going to subclass the QGraphicsTextItem() and see if that paint is being called. It may be the indirection that is causing the issue.
-
Does your item have a geometry ?
If none, then there's no reason for its paint method to be called.