Is there any way to Active PIXEL lines of Scene in JavaFX? - javafx

Is there any way to active Scene's pixel lines? I know there is GridPane but that is not good to measure the pixels. I want to active the Pixel lines of Scene to view each pixel location clearly.

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 get visible scene rect for QGraphicsView

Imagine QGraphicsView is set with the scene that is twice as wider as view's width. sceneRect() will return the whole scene rect. I'd like to get the rect representing the half of the scene with respect to scrollbars' positions.
Get the viewport rectangle with the graphicsView->viewport()->rect() and map it to the scene space with the graphicsView->mapToScene().
I am not totally sure which rectangle you exactly need (this depends from what you want to do) but something like graphicsView->viewport()->contentsRect() or graphicsView->viewport()->geometry() should work.

x,y point shifts when the width is reduced below 200 in QGraphicsScene

I have created a QGraphicsScene
scene = new QGraphicsScene(0,0,200,200);
and draw a line scene.addLine(0,0,100,100,pen); and I got the line correctly drawn from (0,0) to (100,100).
When I change the code to
scene = new QGraphicsScene(0,0,150,200);
And draw the same line scene.addLine(0,0,100,100,pen);, Its x,y point shifts to the right side by 50 pixels. Why does this happen? How to avoid this?
By default, the scene rectangle is centered in the QGraphicsView when it is smaller than the view.
You can use QGraphicsView::setAlignment to change that.
Since the view preferred size, returned by QGraphicsView::sizeHint() is also the scene size, you can adjust the view to fit exactly the scene with:
view->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
which tells the layout to only use sizeHint() to calculate the size of the widget.
Or if the view is not inside a layout, you'll have to set the size with
view->setFixedSize(view->sizeHint());
each time you change the scene rect size.

How to get visible scene rectangle of QGraphicsView?

I'm displaying a map built as rectangle of QGraphicsPixmapitem items (each item stands for one map tile). Because my map is quite large (around 30 MB of PNG files) I want to be able to load pixmaps on demand only when they're visible for user in QGraphicsView and unload when they became invisible.
Is there any way to figure out visible scene rectangle?
This gives you the visible scene rectangle:
sceneRect = graphicsView.mapToScene(graphicsView.rect()).boundingRect()
In case there is a shear or rotation transformation present it gives you the bounding rectangle of the visible scene area. If you do not have such transformations (only shift or zoom) the returned rectangle is the exact scene area.
Now for your real problem of efficiently display a huge tiles map in a scene? You could load the tiles in background and first evaluate if your Qt framework isn't already optimized for big pixmap that are outside the visible range. 30 MB also doesn't sound so big that it wouldn't fit into memory.
QGraphicsView inherits the QWidget::geometry() function. You can use this to determine its location and size within its parent widget. (Outside of its constructor)
The QGrapicsScene can be larger than the QGraphicsView. The default QGraphicsView will add horizontal and vertical scroll bars to house the QGraphicsScene. I imagine you would like to do something like this:
//create a QGraphicsScene (for this example *scene) that is the size of your entire map.
QGraphicsScene *scene=new QGraphicsScene(0,0,mapWidth,mapHeight);
//create a QGraphicsView* named view that is the size of your visible area
//I'm assuming visibleHeight and visibleWidth do not change (this is your viewing window)
QGraphicsView *view=new QGraphicsView(0,0,visibleWidth,visibleHeight);
view->setScene(scene);
Have the user control the x and y position of the scene that triggers some custom signal like sceneMoved(int,int). Before you redraw the scene, call a slot to check the new position of the scene:
connect(this,SIGNAL(sceneMoved(int,int)),this,SLOT(drawScene(int,int)));
void SomeClass::drawScene(int newX, int newY){
//if you already have a pointer to the scene do this, or call
//QGraphicsView::scene();
int oldX=scene->geometry()->x();
int oldY=scene->geometry()->y();
//now that you have your oldX, oldY, newX, and newY, visibleWidth, visibleHeight
//you can determine what you need to redraw, what you need to delete, and what can stay
}
There is still a lot of if..else, but you get the point. I suggest trying to segment your map into squares the size of your visible area.

Using QGraphicsView to display a local map

I'm trying to use QGraphicsView in order to display a map image and draw some items on top of it. The map boundaries are in a Cartesian coordinate system, for example NE(-500,200) to SW(600,-350). I know how to map image pixels <--> my coordinate system.
I would have to achieve the following:
Add a map image to the scene and tell Qt how to map the actual image pixels to scene coordinates.
Add graphic items at their real position, e.g. (-100,200)
Doing (2) is straightforward - simply add the item to the scene. How do I achieve (1)? what should I do after I call scene->addPixmap()?
Edit - A few clarifications:
I'm mapping an indoor area of a few hundred meters
The map will change at real-time in two ways:
The map gets bigger every few seconds
The graphic items move, change colors, etc.
Put the pixmap into a QGraphicsPixmapItem and place it in the scene.
Call setScale() to map the QGraphicsPixmapItem so 1 meter maps to 1 unit in the scene coordinate. ie. setScale(0.1) if 10 pixels in the pixmap equal 1 meter.
Update the pixmap and scale of the item as needed.
Call fitInView() to zoom to the pixmap.
Place other graphic items in the scene. Treat the units of the scene coordinate as meters.
...
Profit! :)

Resources