Infinite grid in Qt - qt

I have created a grid in Qt of the size of graphics view. Whenevr I zoom in/out, the grid is visible in a small area. Drawing is possible in the entire area but grid is confined to a small area.
I have created the grid using the following code:
for(int x = 0; x <= ui->graphicsview->width(); x += 10){
scene->addLine(x,0,x,ui->graphicsView->height(),QPen(Qt::green));
}
for(int y = 0; y <= ui->graphicsView->height(); y += 10){
scene->addLine(0,y,ui->graphicsView->width(),y,QPen(Qt::green));
}
How do I make the grid infinite so that on zoom out, the grid still persists over the area equal to size of graphics view?

You can draw "infinite" lines with the QGraphicsView framework.
Subclass the QGraphicsView or the QGraphicsScene and implement your grid drawing in the QGraphicsView::drawBackground() or QGraphicsScene::drawBackground().
In the drawBackground() method you have to compute intersection points between exposed rectangle (the rect argument of this method) and your grid lines.
Then, use the QPainter::drawLine() with the computed intersection points to draw lines.
I know, this is quite brief explanation of the concept, but I hope it will help.
If not, I can explain it in detail. A couple years ago a was facing similar problem.

The view is only the size of the "camera" looking into a fraction of the scene. If the scene isn't populated with really long lines in all directions, it won't show up on the view when you zoom out. Making the lines the size of the current view is almost worthless once the view changes. Decide what "infinity" means for your application and add all the appropriate lines to the scene. You may need a loading screen as your program is adding all of them.
Or you could do some lazy loading, where you only add the lines to the scene, as the view is panned or zoomed out.
Look into the example of the 40000 chips included with the Qt libraries to see how to do nearly infinite objects, and how to handle level of detail changes as you start to zoom out really far.
Hope that helps.

Related

fit QGraphicsScene to QGraphicsView

I'm trying to draw a stacked bar graph on Qt, i followed the tutorial on the documentation but when i try to put the graph inside a QGraphicsView i get a lo of unused space and can't manage to make the scene fit the view.
My code is the same as the documentation one plus the following to make the scene show up in the view:
QGraphicsScene *scene = new QGraphicsScene(this);
scene->addWidget(chartView);
ui->view->setScene(scene);
And what i get is this
As you can see there is a lot of unused space and it makes the text disappear, i wanted to make the graph fit the view but i can't seem to find a way to do so.
I tried in many different ways using
ui->view->ensureVisible ( scene->sceneRect() );
ui->view->fitInView( scene->sceneRect(),Qt::KeepAspectRatio);
and
ui->view->setSceneRect(0,0,ui->view->frameSize().width(),ui->view->frameSize().height());
but nothing seems to work (the second solution just moves the graph to the top left)
As per the comment... the real issue is the basic sizing of chartView rather than anything to do with QGraphicsView or QGraphicsScene.
When a QWidget is added to a QGraphicsScene the resulting QGraphicsProxyWidget will generally honour the size hint and policy of that widget.
In addition, though, the QGraphicsScene will set the scene rect to the bounding rectangle of all scene items and the QGraphicsView will then position the scene according to whatever viewport anchor is in force. The end result can be visually misleading if the scene has a complex set of items or has a bounding rectangle smaller than that displayed within the GraphicsView.
So if a widget does look odd when added to a QGraphicsScene it's normally a good idea to test by just showing it as a top level window on the desktop and make sure it behaves as expected before going any further.

How to remove Ghost Lines drawn in qgraphicsview

I am trying to make a simple program in which I have added a qgraphics scene and in this I have added a QGraphicsRectItem. I have implemented mouse press event, paint event, bounding rect. Now I have drawn a point on one side of rectangle because there can be multiple rectangle I can drop on screen so just to differentiate between them of different color. Now I can move my rectangle inside graphics seen and can increase the size of rectangle by moving it's one side at a time. The problem that I am facing is when I trying to draw point on one side of rectangle at the time of moving it, it leaves traces on graphics scene. can I remove the ghost lines?
This happens either because your boundingRect method isn't correct, or because you forgot to call prepareGeometryChange before making changes that affect the boundingRect result. Your boundingRect needs to include space for line widths, for example; that's a common mistake.

QGraphicsView framework performance issue for large number of items

I am using qt 5.0.1 in windows. I am creating 200k+ custom QGraphicsItem. I have added basic functionalists in these custom items, like mouse hover, mouse click etc.. This items are static. But on top of these items I add some items (200 max) which animates (different property animation, scale, opacity etc).
When I add those items in the scene it become extremely slow, in a relatively powerful workstation.
QGraphicsScene *scene = new QGraphicsScene();
scene->setSceneRect(0, 0, width, height);
scene->setBackgroundBrush(Qt::darkGray);
scene->setItemIndexMethod(QGraphicsScene::NoIndex);
QGraphicsView *view = new QGraphicsView( scene );
view->setRenderHint(QPainter::Antialiasing, false);
view->setResizeAnchor(QGraphicsView::AnchorViewCenter);
view->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
view->resize( width, height );
view->setOptimizationFlags(QGraphicsView::DontSavePainterState);
view->setViewportUpdateMode( QGraphicsView::SmartViewportUpdate);
view->setTransformationAnchor(QGraphicsView::AnchorUnderMouse);
view->setCacheMode(QGraphicsView::CacheBackground);
view->setViewportUpdateMode( QGraphicsView::FullViewportUpdate);
view->show();
I have tried the following, but it makes the rendered view extremely bad, as it seems to enable antialiasing, but I need some pixel label precision.
view->setViewport(new QGLWidget( QGLFormat(QGL::SampleBuffers)));
Am I missing some important Qt programming tricks? Please suggest. I can post the code, or explain more if in case please let me know. Thanks in advance.
When you have a lot of items, the bottleneck is when you have them many on the screen at the same time, which would mean they are fairly small. In such cases, it is advisable to resort to using different LOD - that's level of details. When the item is small, draw a simplified version of it. Combine that with LOD baking and caching and an OpenGL widget to draw onto and you could easily get tens or even hundreds of thousands items at a time.

Drawing a pixmap using QPainter::drawPixmap in qt

I am able to paint a pixmap by using QPainter::drawPixmap, but I am having trouble with the sizing. The pixmap is being drawn onto many different scenes. Some of the scenes are very large, and some are very small. This results in the pixmap drawn being either looking very large or very small, depending on the size of the scene (or viewport, whatever its called). I need the pixmap to look the same size everytime, regardless of the dimensions of the scene it is being placed into.
Basically, I want it to work similar to drawPoint, where you can specify the length and width of the point in pixels, so the point looks the same size every time.
The following line of code is inside my paint function of the QGraphicsItem I subclassed:
painter_p->drawPixmap( pos(), MYPIXMAP );
with pos() returning the QPointF I need to draw the pixmap at.
Can't you use QGraphicsPixmapItem? It'd do exactly what you want.

Cocos2d grid design for drawing lines

Hello guys
I have a small problem while designing a iphone game with a grid using cocos2d.
The game needs a 10x10 grid in the middle of the screen (it is not covering the entire screen).
A line is drawn at runtime where the user touches two points in the grid.
Question: would tilemap be ideal for this problem? As i need to verify the co-ordinates do belong to the grid or not when the user touches a point would tilemap be useful?
Question: Is there any better way of solving this in cocos2d. Please help me out.
Thanks
I wouldn't recommend using tilemap for this. Personally I'd do it all with math.
Lets for arguments sake say your grid squares are 10px by 10px.
You now instantly know the positions of the rects for each square.
top right square would be (90, 0, 10, 10), this obviously doesn't include the positioning of your grid, but you can easily add that onto this by adding.. (90+gridPos.x, 0+gridPos.y, 10, 10).
Then you just check your touches intersect the rects of the grids.
Drawing a line is fairly simple, i imagine you'd draw it from the center of the 2 grid points.
So if the line started in the top right grid square it's initial point would start at (90+gridPos.x, 0+gridPos.y, 5, 5), or (90+gridPos.x, 0+gridPos.y, gridSquareHeight/2, gridSquareWidth/2)
Using cocos2d it's pretty easy to also make every square a touchable sprite, that can react when touched however you like, sending a message back to a delegate or even just doing a visual effect.
There are tonnes of possibilities for solving this problem.

Resources