How to put several QImage in a QGraphicsView? - qt

I have a scene where several items are added. The problem is that when the items are displayed, they are overlapping. Is there any way to indicate in the QGraphicsView or QGraphicsScene the position where each item should appear?

Yes, you have to use QGraphicsItem::setPos() method.
I suppose you added a QGraphicsPixmapItem, so it could look like :
QGraphicsScene *scene = ... ; // your scene
QImage image = ... ; // the QImage you want to add to the scene
QPixmap pixmap = QPixmap::fromImage(image) ;
// add image item to the scene
QGraphicsPixmapItem * imageItem = scene->addPixmap(pixmap) ;
// modify item's position in scene coordinates
QPointF imagePos = ... ; // whatever scene pos you want
imageItem->setPos(imagePos) ;

Related

typecast qgraphicsitem to qgraphicswidget

my qgraphicsscene is having qgraphicswidget which constantly adding qgraphicsLayoutItem. in graphicsView i need to get the qgraphicswidget geometry in scene coordinated.
i tried
QList items = scene()->items();
and check its with type
foreach (QGraphicsItem *item, items) {
if(item->type() == ItemType)
{
}
but how to convert item to qgraphicswidget and change its gemoetry to scene coordinates.
normal item.boundingRect returns constantly 0,0, 10x10
The bounding rect of the item is in item coordinates. To map it to scene coordinates, use QGraphicsItem::mapToScene():
const QRectF mapped = item->mapToScene(item->boundingRect());
To cast a QGraphicsItem, you can simply use dynamic_cast or static_cast, or the special qgraphicsitem_cast:
auto widget = qgraphicsitem_cast<QGraphicsWidget*>(item);
To map the coordinates, casting shouldn’t be necessary though.

QT: I need to get coordinates of image added to QGraphicsView via QGraphicsScene

When I add small image to QGraphicsView, is there a way to get coordinates of image pixel? I have used rubberband for my custom class QGraphicsView but I can only get the QGraphicsView coordinates.
I guess you want to get pixel from a given position. Assume the given position comes from mouse position.
Say, a class inherited from QGraphicsView:
MyView::MyView( QWidget *parent=0 ) : QGraphicsView(parent)
{
setScene( new QGraphicsScene( this ) );
this->scene()->addPixmap(QPixmap::fromImage(this->image)); // this->image is a QImage
}
Then, implement mouse event
void MyView::mouseMoveEvent( QMouseEvent* event )
{
QPointF pos = mapToScene( event->pos() );
QRgb rgb = this->image.pixel( ( int )pos.x(), ( int )pos.y() );
}

Adding QGraphicsView and QGraphicsScene to a label in Qt

I have a stacked widget on which I have a QLabel. I display an image on this label. I want to zoom and pan this image and I am trying to use the QGraphicsView technique. However a new window opens.
This is what I am doing.
scene = new QGraphicsScene(this);
view = new QGraphicsView(this);
QPixmap pix("/root/Image);
label->setPixmap(pix);
scene->addWidget(label);
view->setScene(scene);
view->setDragMode(QGraphicsView::scrollHandDrag);
view->show();
Can someone please suggest me what I should do. I want the label to act like the QGraphicsView.
Thank You :)
You create a scene and view and add the label to the scene, then tell the view to show itself with: -
view->show()
If, as you state, you want the QGraphicsView on the label, don't add the label to the scene, but add the QGraphicsView to the label: -
QLabel* pLabel = new QLabel(mainWindow); // setting mainWindow as the parent
QGraphicsView* pView = new QGraphicsView(pLabel) // set the label as the parent of the view.
You do not need to call show, as the label will handle that for you, assuming the label is on a Widget that is already displayed.
Now, instead of setting the pixmap on the label, create a pixmap in the scene with: -
pScene->addPixmap(pixmap);

Moving a QPixmap to the corner of a QGraphicsScene

I have a QGraphicsView and a QGraphicsScene connected like this:
graphicsScene->setSceneRect(this->graphicsView->rect());
graphicsView->setScene(this->Scene);
Then I load an image and add it to the scene:
QPixmap pixmap;
pixmap.load(fileName);
pixmap = pixmap.scaled(this->graphicsView->size());
QGraphicsPixmapItem* item = this->Scene->addPixmap(pixmap);
Now, as described in the documentation, the image corner is at (0,0), which is not the corner of the graphicsScene. I know I can position the resulting pixmap by doing:
item->setPos(this->Scene->sceneRect().x(), this->Scene->sceneRect().y());
However, I can't seem to make sense of the coordinates of the rect's of the scene or the view. Can anyone explain how I would move the pixmap to the corner of the scene/view?
Thanks,
David
EDIT: Here is the full form constructor. The QGraphicsView was created in Qt Designer and is inside of a GridLayout:
Form::Form(QWidget *parent)
: QWidget(parent)
{
setupUi(this);
QGraphicsScene* scene = new QGraphicsScene;
scene->setSceneRect(this->graphicsView->rect());
this->graphicsView->setScene(scene);
QPixmap pixmap;
pixmap.load("image.png");
pixmap = pixmap.scaled(this->graphicsView->size());
scene->addPixmap(pixmap);
}
I also tried this:
QGraphicsScene* scene = new QGraphicsScene;
this->graphicsView->setScene(scene);
QPixmap pixmap;
pixmap.load("/home/doriad/glasses.jpg");
QGraphicsPixmapItem * item = scene->addPixmap(pixmap);
this->graphicsView->fitInView (item);
but the image appears tiny, rather than filling up the view like I would expect. Can anyone explain this?
The full project and image are available here: daviddoria.com/Uploads/qt/QPixmapPosition
Don't worry about scaling the pixmap yourself or even translating it, let the view do it for you.
Use graphicsView->fitInView(pixmap); but you should read the documentation for :
Qt's Graphics View Framework
void QGraphicsView::setSceneRect (QRectF )
void QGraphicsView::translate ( qreal dx, qreal dy )
void QGraphicsView::fitInView ( const QGraphicsItem * item, ... )
The way that QGraphicsScene and QGraphicsView interact is that you can have a single scene with at least one or more views.
A good example I like to think of is a zoomed in view of part of a map with a mini view of the entire map in the corner. There are two views, one of part of the map and one of the entire map, with one scene, the map itself.
So you put items in your scene and all the items in the scene are drawn relative in size to each other. The "scene rect" of your view, by default, scales to fit the items in the view until one unit in the scene is one pixel in the view or until it needs to zoom out to fit all the items in your scene.
If you call fitInView(someItem) it should scale your view of the scene so that the item specified fills it up and translates the view so that it is centered. If you need to translate or scale it more use the translate or scale functions in QGraphicsView.
When you are jumping between coordinate systems of your scene and view with your QRect's or QPoint's, use the helper functions: mapToScene and mapFromScene from QGraphicsView.
Try this:
QGraphicsScene* scene = new QGraphicsScene;
scene->setSceneRect(graphicsView->sceneRect());
QPixmap pixmap;
pixmap.load("/home/doriad/glasses.jpg");
pixmap=pixmap.scaledToWidth(this->graphicsView->width());
QGraphicsPixmapItem * item = scene->addPixmap(pixmap);
graphicsView->setScene(scene);
By default, the pixmap will be at (0,0) in the scene, and the scene will be at (0,0) in the view. QWidgets are sized by pixels. If you had a QGraphicsView the size of the screen and the resolution is 1440 x 900, you can position objects in that view from (0,0) or the top left corner of the screen, to (1440,900) the bottom right corner of the screen. Most QGraphicsItems are placed with reference to their top left corner. So placing a pixmap at (0,0) aligns the top left corner of the pixmap with the top left corner of the scene it's placed in. If your pixmap 'hangs off the bottom' of your view, try using:
pixmap=pixmap.scaledToHeight(this->graphicsView->height());
If you use the function:
this->graphicsView->fitInView (item);
The graphicsView will only scroll to the point where your item fits in the view.
I downloaded David's code and ran it two ways. Click the links to see the results.
1) with pixmap=pixmap.scaledToHeight(this->graphicsView->height());
2) with pixmap=pixmap.scaledToHeight(200);
I don't know enough to explain why this is happening, but I thought it would be a useful data point.
It turns out the problem was that the GraphicsView was in a layout. In my example, the resizing of the image was done in the Form constructor. Apparently this is before the layout takes its shape? I moved the code to a pushButton and when I click it the image is sized how I would expect.
I got the image to stay sized to the GraphicsView in the Layout by subclassing QGraphicsView and reimplementing :
class CustomGraphicsView: public QGraphicsView
{
Q_OBJECT
{
void resizeEvent ( QResizeEvent * event )
{
emit resized();
}
signals:
void resized();
}
Then I connect this resized() signal to a slot that simply calls this->View->fitInView (this->ImageToTraceItem);
David

Meaning of first two parameters of QGraphicsScene constructor

I can construct a QGraphicsScene by using constructor below:
QGraphicsScene::QGraphicsScene ( qreal x, qreal y, qreal width, qreal height, QObject * parent = 0 )
For example:
QGraphicsScene scene(-350, -350, 700, 700);
I know the first two parameters represent a point, but in which coordinate system?
When I create a QGraphics object and show this view like this:
QGraphicsView view(&scene);
view.show();
Where will this view appear on my device?
Is the location controlled by first two parameters mentioned above?
The first two parameter mean, when a view focus on this scene, which point in the scene is the top-left corner of the view.
In your code, the -350,-350 will be the top-left corner of the view window.
Here's another example:
QGraphicsScene *scene = new QGraphicsScene;
scene->setSceneRect(-360,-240,720,480);
QGraphicsView *view = new QGraphicsView(this);
view->setScene(scene);
if you try to add item without telling where to show it, it will show at (0,0). And in the code above, is the center of the view.

Resources