1

我想绘制彩色瓷砖作为 QGraphicsscene 的背景,并使用 QGraphicsView 为场景提供平移和缩放功能。首先,我使用 QGraphicItems 来绘制每个图块。因为我有很多图块,所以在平移或缩放时这是一个相当大的性能问题,但是由于我不需要修改图块的任何部分,所以我切换到使用以下代码生成 QPixmap:

void plotGrid(){
    Plotable::GraphicItems items;
    append(items,mParticleFilter.createGridGraphics());
    append(items,mParticleFilter.getRoi().mRectangle.createGraphics(greenPen()));
    scaleItems(items,1.0,-1.0);
    QGraphicsScene scene;
    showItemsOnScene(items,&scene);
    QRectF boundingRect = scene.itemsBoundingRect();
    double cScale = ceil(1920.0/boundingRect.size().width());
    QSize size(boundingRect.size().toSize()*cScale);
    QPixmap pixmap(size);
    pixmap.fill(Qt::transparent);
    QPainter p(&pixmap);
    //p.setRenderHint(QPainter::Antialiasing);
    scene.render(&p);
    p.end();
    QGraphicsPixmapItem* item = new QGraphicsPixmapItem(pixmap);
    item->setOffset(boundingRect.topLeft()*cScale);
    item->scale(1/cScale,1/cScale);
    mpView->showOnScene(item);
  }

虽然这解决了缩放和平移问题,但生成像素图的时间引入了一些明显的延迟,可能是因为我首先创建了一个场景然后渲染它。有没有更快的方法从 QGraphicItems 开始动态生成 QPixmap ?

只是为了完整性,瓷砖的图像:在此处输入图像描述

4

1 回答 1

0

所以我终于至少通过了中间场景。以下代码仅依赖于 QPainter 来呈现像素图。我的主要问题是正确进行所有转换。否则它是非常简单的......在我的场景中,这个版本将处理时间减半到 500 毫秒。绘制项目花费了 450 毫秒。如果有人对更多改进有更多建议,那将是最受欢迎的(顺便说一下,改变决议并没有多大帮助)

void SceneWidget::showAsPixmap(Plotable::GraphicItems const& items){
    QRectF boundingRect;
    boostForeach(QGraphicsItem* pItem,items) {
      boundingRect = boundingRect.united(pItem->boundingRect());
    }
    QSize size(boundingRect.size().toSize());
    double const cMaxRes =1920;
    double const scale = cMaxRes/boundingRect.size().width();
    QPixmap pixmap(size*scale);
    pixmap.fill(Qt::transparent);
    QPainter p(&pixmap);
    //p.setCompositionMode( QPainter::CompositionMode_Source );
    p.translate(-boundingRect.topLeft()*scale);
    p.scale(scale,scale);
    QStyleOptionGraphicsItem opt;
    boostForeach(QGraphicsItem* item,items) {
      item->paint(&p, &opt, 0);
    }
    p.end();
    QGraphicsPixmapItem* item = new QGraphicsPixmapItem(pixmap);
    item->scale(1.0/scale,-1.0/scale);
    item->setOffset(boundingRect.topLeft()*scale);
    showOnScene(item);
}
于 2012-11-18T14:50:26.560 回答