缩小缩小的QPixmap:无法恢复原始大小

len*_*ena 5 qt qpixmap qgraphicsview qgraphicsscene

我正在制作一个应用程序,我需要在图片上方绘制图形(即矩形)并调整整个场景的大小.我正在使用QGraphicsViewQGraphicsScene.我无法弄清楚为什么,但是当我使用时,fitIntoView()我无法在图片顶部绘制数字(它们可能是在图片后面或在边界之外绘制的).

现在我正在使用QPixmap.scaled()以使图像适合QGraphicsScene.它工作正常,除非我需要显示一个大图像,然后放大.因为我缩放图像以适应,它变得更小,当我称QGraphicsView.scale()图像缩小为小,我找不到"缩放的方法将图像恢复为原始尺寸.

在代码的缩放部分,我试图用它没有缩放的副本替换像素图,但我不能用与我的图形缩放相同的比例缩放它.任何帮助,将不胜感激!


在这里,我加载图像并缩放它

QPixmap pix;
pix = pixmap->scaled(wid, hei,Qt::KeepAspectRatio, Qt::SmoothTransformation);
scn = new QGraphicsScene(pw);
pw->setScene(scn);
p = new QGraphicsPixmapItem(pix);
p->setPixmap(pix);
scn->addItem(p);
Run Code Online (Sandbox Code Playgroud)

我画这样的数字

rect = new QGraphicsRectItem(x,y,w,h);
rect->setPen(QPen(getColor(), 1, Qt::SolidLine, Qt::FlatCap));
scn->addItem(rect);
Run Code Online (Sandbox Code Playgroud)

这是我如何缩放

pw->scale(scaleFactor_,scaleFactor_);
Run Code Online (Sandbox Code Playgroud)

更新: 现在我QWidget在顶部有一个带有工具栏的工具栏,其余的可用空间充满了自定义QGraphicsView.这是一个用于抓取鼠标事件的派生类,除了事件处理程序之外别无选择.我在我的widget的构造函数中添加了PainterGraphicsView:

pw = new PainterGraphicsView();
ui->gridLayout_3->addWidget(pw);
Run Code Online (Sandbox Code Playgroud)

我每次加载新图像时都会重新创建场景:

scn = new QGraphicsScene(pw);
pw->setScene(scn);
QRect r = QRect(0,0, pw->width()-5, pw->height()-5);
scn->setSceneRect(r);
Run Code Online (Sandbox Code Playgroud)

加载图像后,我可以在其上绘制图形,它看起来像这样:

在此输入图像描述

缩放内容如下所示:

在此输入图像描述

正如您所看到的,数字与像素图一起缩放,这正是我需要它工作的方式.我唯一需要解决的是缩放像素图的低质量.正如我已经说过的,我尝试用我的ZoomIn方法中的原始像素替换像素图,但我无法保存数字的位置.

void DrawerWidget::on_btZoom_clicked()
{
    p->setPixmap(pix); //p is QGraphicsPixmapItem, pix is an original pixmap
    p->setScale(0.5); //how can I scale the pixmap together with figures?? How to calculate the required scale?
    pw->scale(scaleFactor_,scaleFactor_);
}
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述


更新2:

关于我的绘图数字方法的简短解释:( 虽然我个人认为这不是问题,我感兴趣的是有一种方法可以使用setScale()来缩放QGraphicsPixmapItem以适应QGraphicsView大小)

我正在从鼠标事件参数中获取start_并进行end_协调(QMouseEvent *e)

 end_=pw->mapToScene(e->pos());
 start_=pw->mapToScene(e->pos());
Run Code Online (Sandbox Code Playgroud)

我在mousepress上添加了这个数字:

rect = new QGraphicsRectItem(start_.x(),start_.y(),1,1);
scn->addItem(rect);
Run Code Online (Sandbox Code Playgroud)

我在鼠标移动时重绘了这个数字

rect->setRect(Graphics::GetFigure(start_.x(),start_.y(),end_.x(),end_.y()));
Run Code Online (Sandbox Code Playgroud)

GetFigure是一个计算数字矩形的方法,这是它的主要部分:

 static QRectF GetFigure(double startX, double startY, double finalX, double finalY)
    {
      QRectF shape;
      shape.setX(startX);
      shape.setY(startY);
      shape.setWidth(qFabs(finalX - startX));
      shape.setHeight(qFabs(finalY - startY));
      return shape;
   }
Run Code Online (Sandbox Code Playgroud)

dte*_*ech 5

缩放操作具有破坏性,一旦缩小,最终得到的数据会比开始时少。

如果您希望能够恢复原始大小,请保留原始像素图的副本。

QGraphicsPixmapItem您可以从原始的、未缩放的像素图创建,然后用于QGraphicsPixmapItem::setScale(qreal)更改级别图形项目的大小,而不是级别像素图数据的大小。这样缩放不应该具有破坏性,并且如果将其放大到原始尺寸,也不应该损失质量。

如果您想缩放多个项目(并且不遇到不同的转换原点问题),您有几个选择:

  • 缩放整个视图 - 这将缩放所有内容
  • 将项目添加为父项目的子项目,然后缩放父项目也会缩放其子项目

项目转换从父级到子级累积

所有项目都重新设置为组的父级,并且它们的位置和变换都映射到组