2016-02-26 142 views
4

我想提出一个应用程序,我需要画一幅画上面的数字(即矩形),并调整整个场景。我正在使用QGraphicsViewQGraphicsScene。我无法弄清楚为什么,但是当我使用fitIntoView()时,我无法在图片的顶部绘制数字(它们可能被绘制在图片的后面或边界之外)。放大缩小的QPixmap:无法恢复原来的大小

现在我使用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); 

我得出这样的

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

的数字,这里是我如何放大

pw->scale(scaleFactor_,scaleFactor_); 

更新: 现在我有一个QWidget顶部有一种工具栏,其余的自由空间填充自定义QGraphicsView。这是一个抓取鼠标事件的派生类,除了事件处理程序外,没有什么更多的了。我在我的窗口小部件的构造将PainterGraphicsView:

pw = new PainterGraphicsView(); 
ui->gridLayout_3->addWidget(pw); 

每次我重建现场我一个新的图像加载到它:

scn = new QGraphicsScene(pw); 
pw->setScene(scn); 
QRect r = QRect(0,0, pw->width()-5, pw->height()-5); 
scn->setSceneRect(r); 

我装的像,我可以在绘制图形之后它的上面,它看起来像这样:

enter image description here

而且缩放内容是这样的:

enter image description here

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

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_); 
} 

enter image description here


更新2:

我附图方法的简短说明:(虽然我个人并不认为这是问题,我m感兴趣的是有一种方法来缩放QGraphicsPixmapItem使用setScale(),以适应QGraphicsView大小)

我越来越start_end_鼠标事件参数坐标(QMouseEvent *e)

end_=pw->mapToScene(e->pos()); 
start_=pw->mapToScene(e->pos()); 

我添加了数字上mousepress:

rect = new QGraphicsRectItem(start_.x(),start_.y(),1,1); 
scn->addItem(rect); 

我重绘上移动鼠标图

rect->setRect(Graphics::GetFigure(start_.x(),start_.y(),end_.x(),end_.y())); 

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; 
    } 
+0

我不明白为什么要扩展QPixmap。如果您想缩放图像并保持分辨率,则可以缩放QGraphicsPixmapItem。 – Fabio

+0

Hi @Fabio!感谢您的答复!我缩放QPixmap,因为我可以将其缩放以适合宽度和高度,并且使用QGraphicsPixmapItem我必须以某种方式计算缩放比率,而我不知道该如何... :( – lena

+0

)可以使用小于QGraphicsScene的图像大小,但我需要使大图像变小,据我所知我需要使用从0到1的缩放比例,但我有一个奇怪的结果,我只是尝试'setScale(0.5)',我期望QGraphicsPixmapItem有两倍的大小,但我只有一个包含原始图像部分的广场,我可以在这里错过什么? – lena

回答

3

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

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

您可以从原始未缩放的像素图创建QGraphicsPixmapItem,然后使用QGraphicsPixmapItem::setScale(qreal)更改级别图形项目的大小,而不是级别像素图数据。这种缩放不应该具有破坏性,如果将其扩展到原始大小,则不应该失去质量。

如果你想扩展多个项目(而不是碰上不同的转换起源的问题),你有几种选择:

  • 规模整个视图 - 这将扩大一切
  • 添加的项目,如儿童父项,然后缩放家长将扩展自己的孩子以及

项目转换从父积累到孩子

  • 使用createItemGroup()添加项目到组:

的项目都重设父到组,他们的立场和 转换映射到组

+0

是的,我试着这个解决方案之前我张贴在SO,但我不知道如何扩大'QGraphicsPixmapItem'连同数字我把它画在上面。请看我编辑的问题。 – lena

+0

@lena - 请参阅我的编辑 – dtech

+0

使用您的方法,在我的缩放方法中,我用原始副本替换了按比例缩小的“QPixmap”,但滚动条没有像使用QGraphicsView.scale()那样出现, m无法浏览图像。我在这里错过了什么? – lena

1

我认为你的问题是你设置场景rect为QGraphicsView矩形。这是不正确的,因为窗口参考系统与场景参考系统不同。 您不需要设置场景矩形,因为在添加一些项目时场景矩形会自动增大。如果要将场景矩形限制为像素矩形,可以将场景矩形设置为边界矩形。

您不需要缩放原始像素图。要缩放您的视图,只需拨打QGrapicsView::scale即可。您也可以拨打QGrapicsView::fitInView将图像放入视图中。

如果您需要添加用户(即窗口坐标),您可以使用QGraphiscView::mapToScene映射窗口绘制一些rects坐标场景坐标

我建议阅读参考系统的文档:The Graphics View Coordinate System

+0

我希望场景与“QGraphicsView”具有相同的大小和位置,即填充窗口的所有空闲空间,是否可行?当我尝试'fitInView'方法,然后试图画出他们没有绘制的数字。这也可能是由这种坐标不一致造成的吗? – lena

+0

我复制了我对绘制图形的评论:'void DrawerWidget :: onMousePress(QMouseEvent * e){start_ = pw-> mapToScene(e-> pos());结束_ = PW-> mapToScene(E-> POS()); }'我从我的子类'QGraphicsView'中捕获信号,并使用'start_'和'end_'点在鼠标移动上绘制图形 – lena

+0

使用mapToScene是正确的,但是不清楚如何使用start_ end end_。请发布更多代码。另外一定要设置一个正确的zValue的项目 – Fabio