0
votes

Here is what I want to do.

I need to draw in a QGraphicsView a series of rectangles that are aligned left and right. By this I mean that if rectangle i has posion (0,y) rectangle i+1 needs to have position (0,max) where max is such that the right side of the rectangle "touches" the right side of the QGraphicsView.

When the window is resized I need to recalculate the value of max such that the rectangle is always touching the right side of the screen.

Here is how I add my scene (this references a class that inherits QGraphicsView)

scene = new QGraphicsScene(this);
this->setScene(scene);
this->setAlignment(Qt::AlignTop|Qt::AlignLeft);

To add a rectangle that touches the left border I add it a (0,yvalue,width,height).

How do I calculate the value of X so that that the rectangle will touch the right border?

2
Are you able to use QML? I recently switched from QGraphicsView to QML for drawing things like this and the productivity impact is huge. - Sohail
I don't even know what QML is... to be honest. I'm using Qt 5.1.1. is it available ther? What about compatibility? I care more about that than performance... - aarelovich
Oh, then you'll love it: doc.qt.io/qt-5/qmlapplications.html Compatibility is fine. I ship QML apps on the 3 desktop platforms but I use Qt 5.6 to do so. I couldn't tell you the compatibility story with Qt 5.1.1. - Sohail
It seems this is for designing interfaces. What I wnat to do is generate these rectangle dinamically. Can it also be done with this? - aarelovich
You need to map your rectangle to scene, and get the right() coordinate of the bounding rect. I will post a little example in amin. - Thalia

2 Answers

0
votes

Ok. So this should go in the resize event of the QGraphicsView. But this does what I wanted:

void AView::resized(){

    scene->clear();
    QSize newsize = this->size();

    qreal w = newsize.width()*.99;
    qreal h = newsize.height()*.99;
    this->setSceneRect(0,0,w,h);
    scene->setSceneRect(0,0,w,h);

    qreal rectwidth = 100;
    qreal newx = w - rectwidth;
    left = new QGraphicsRectItem(0,0,rectwidth,100);
    left->setBrush(QBrush(Qt::red));
    right = new QGraphicsRectItem(newx,100,rectwidth,100);
    right->setBrush(QColor(Qt::blue));

    scene->addItem(left);
    scene->addItem(right);

}

In this way the blue rectangle is pretty much always at the border. Aslo there is no stretching of the image. There is a gap between the right borders which increases due to the window resizing, but it seems that the size returned by this->size() is slightly larger than the "white area" that you see on screen. Adding the .99 gives a much better results from my experiments.

0
votes

This little example should calculate the shift and move all items from a selection or list of items, based on alignment you desire (I showed right, but let, center, top, bottom would be the same).

QRectF refRect = scene()->sceneRect();
QList<QGraphicsItem*> sel = allItemsYouWantAligned;  // scene()->selectedItems();  for example

foreach(QGraphicsItem* selItem, sel)
{
    qreal dx = 0, dy = 0;
    QRectF itemRect = selItem->mapToScene(selItem->boundingRect()).boundingRect();
    if(align_right)
        dx = refRect.right() - itemRect.right();
    else
        .. calculate either dx or dy on how you want to align
    selItem->moveBy(dx, dy);
}

Re-reading the question - I see you don't really need to move rectangle, but create new larger and larger rectangles.

Your solution is simple enough. If you want to resize instead of move - you would have to setRect() on your items by dx increment:

QRectF r = selItem->rect();
r.setWidth(r.width + dx);
selItem->setRect(r);