Увеличить QGraphicsItem, чтобы соответствовать QGraphicsView - PullRequest
2 голосов
/ 12 апреля 2011

Я пытаюсь создать QGraphicsView, который позволит кому-то масштабировать текущий QGraphicsItem, чтобы он соответствовал размеру окна QGraphicsView.

Я переопределил QGraphicsItem для создания пользовательской версии, и я реализовал некоторые методы, чтобы он знал, насколько он был масштабирован (который всегда пропорционален оригиналу, поэтому есть только один коэффициент масштабирования - одинаковый для ширины и высота).

Итак, в установщике scaleFactor есть следующее:

void ImagePixmapItem::setScaleFactor(float sf){
    scaleFactor = sf;
    this->boundingRect().setWidth(this->boundingRect().width()*scaleFactor);
    this->boundingRect().setHeight(this->boundingRect().height()*scaleFactor);

}

И в моей основной форме у меня есть следующее:

   QRect portRect = ui->graphicsView->viewport()->rect();
    double scaleFactorX;
   if(portRect.width() <= (item->boundingRect().size().width()))
       scaleFactorX =portRect.width() /(item->boundingRect().size().width());
   else
       scaleFactorX = (item->boundingRect().size().width())/portRect.width();

    qDebug("Scalefactor: %4.3f \n", scaleFactorX);
    qDebug("item width: %4.3f \n", item->boundingRect().size().width());
    qDebug("item height: %4.3f \n", item->boundingRect().size().height());
    item->setScaleFactor(scaleFactorX);
    item->scale(scaleFactorX,scaleFactorX);

Где item является одним из тех ImagePixmapItem с.

Это хорошо работает в первый раз - мое изображение больше, чем область просмотра, и оно хорошо масштабируется, чтобы соответствовать окну (по крайней мере, по ширине). Однако, если я нажму кнопку еще раз, вернутся те же значения для scaleFactorX и item ширина и высота.

Можете ли вы изменить boundingRect изображения после его преобразования? Если нет, что мне делать?

1 Ответ

3 голосов
/ 12 апреля 2011

Прежде всего, QGraphicsItem::boundingRect() возвращает копию прямоугольника. Изменение не влияет на сам предмет. Чтобы изменить геометрию элемента, вам нужно переопределить эту функцию и вернуть другой прямоугольник. И позвоните prepareGeometryChange(), когда вы действительно измените его.

Теперь, если все, что вам нужно, это поместить элемент в область просмотра QGraphicsView, используйте QGraphicsView::fitInView().

Изменение преобразования элемента очень отличается от изменения преобразования из сцены в представление. Первый изменяет способ размещения элемента на сцене по отношению к другим элементам. Последний сохраняет связь и влияет только на то, как сцена «отражается» на виде.

Не имеет большого значения, если у вас есть один предмет на сцене. Просто имейте в виду, что когда вы имеете дело с более сложной сценой, преобразование элементов имеет дело с математической моделью вашего мира, а не с тем, как его просматривать.

Edit:

Я просто перечитал твой код. Оказывается, вы неправильно рассчитали масштабный коэффициент. Вот основной, не проверенный код:

QRect itemSize = graphicsView->mapFromScene(item->sceneBoundingRect()).boundingRect().size();
QRect scaledSize =itemSize.scale(graphicsView->viewport().size(), Qt::KeepAspectRatio);
double ratio = qMin((double)scaledSize.width()/itemSize().width(), (double)scaledSize.height()/itemSize().height());
item->setTransform(QTransform::fromScale(ratio,ratio), true);

Смысл в том, чтобы использовать sceneBoundingRect вместо boundingRect, поскольку boundingRect - это локальные границы элемента, которые всегда одинаковы независимо от преобразования элемента. И sceneBoundingRect - границы после того, как все transformations применены.

...