Reputation: 1
I'm currently struggling with populating a qgraphicsscene with many (> 1Million) objects (Polygons, Lines, Points). What I've observed is, that when creating randomly 100000 Polygons, I'm already ending up withe 130MB memory consumption. (The simple example below is based on a default Qt-Project using the View.cpp of the chip-demo example)
QtGrafikTestBasic::QtGrafikTestBasic(QWidget *parent): QMainWindow(parent)
{
ui.setupUi(this);
QSplitter *h1Splitter = new QSplitter;
QSplitter *vSplitter = new QSplitter;
vSplitter->addWidget(h1Splitter);
View* view = new View("asdf");
h1Splitter->addWidget(view);
QHBoxLayout *layout = new QHBoxLayout;
layout->addWidget(vSplitter);
setLayout(layout);
setCentralWidget(view);
QBrush *brush = new QBrush();
brush->setColor(Qt::blue);
brush->setStyle(Qt::SolidPattern);
QPen *pen = new QPen();
pen->setWidth(0);
QGraphicsScene *scene = new QGraphicsScene;
srand ( time(NULL) );
int m_PolyWidth = 10;
for (int i = 0 ; i < 100000; i++)
{
double lBaseX = rand() % ((int)floor(width()) - m_PolyWidth);
double lBaseY = rand() % ((int)floor(height()) - m_PolyWidth);
QPolygonF polygon;
polygon << QPointF(lBaseX, lBaseY);
polygon << QPointF(lBaseX + m_PolyWidth, lBaseY);
polygon << QPointF(lBaseX + m_PolyWidth, lBaseY + m_PolyWidth);
polygon << QPointF(lBaseX, lBaseY + m_PolyWidth);
scene->addPolygon(polygon, *pen, *brush);
}
view->view()->setScene(scene);
}
So what am I doint wrong here / where can I improve? I've read some posts of creating an own class like the chip-example, so I simply used the chip example but also there I've encountered the problem that as soon as I change the part which uniformly distributes the chips from item->setPos(QPointF(i, j));
to a random distribution item->setPos(QPointF(lBaseX, lBaseY));
, the memory consumption explodes also here...
So, what is the most performant and least memory-consuming way of drawing polygons, (poly-)lines and points in Qt?
Upvotes: 0
Views: 304
Reputation: 27629
When you call addPolygon on the graphics scene, it creates a QGraphicsPolygonItem and adds that to the scene.
Each item you add has various properties that include position, orientation, brush, pen and allows the scene to handle collision detection. Also, each item is going to have its paint function called, which is quite an overhead.
The first thing to do here is to see what performance you'd gain with using a QPainterPath. Create a QPainterPath and add the polygons to that: -
QPainterPath* painterPath = new QPainterPath;
for (int i = 0 ; i < 100000; i++)
{
double lBaseX = rand() % ((int)floor(width()) - m_PolyWidth);
double lBaseY = rand() % ((int)floor(height()) - m_PolyWidth);
QPolygonF polygon;
polygon << QPointF(lBaseX, lBaseY);
polygon << QPointF(lBaseX + m_PolyWidth, lBaseY);
polygon << QPointF(lBaseX + m_PolyWidth, lBaseY + m_PolyWidth);
polygon << QPointF(lBaseX, lBaseY + m_PolyWidth);
painterPath->addPolygon(polygon);
}
If you add the painterPath to a class derived from QGraphicsItem, you can then get the painterPath to draw in the item's paint function: -
painter.drawPath(painterPath);
This will be considerably quicker. Just ensure you're not adding the polygons to the painter path inside the paint function. The paint function should do nothing, but render the item.
Upvotes: 1