快速绘制qDeclarativeItem

Fast drawing on a qDeclarativeItem

本文关键字:qDeclarativeItem 绘制      更新时间:2023-10-16

假设我们有两个qDeclarativeItem放在彼此的顶部。底部项目包含一个背景图像(大部分时间保持不变)。顶部项目包含一堆简单的项目(线,弧…),可以直接使用鼠标编辑。

问题:当在顶层绘制时,底层也完全重新绘制。考虑到我在那里有一个大的图像,重新粉刷它是非常缓慢的。

作为上面所说的一个例子,下面是一些代码:

Q_DECL_EXPORT int main(int argc, char *argv[])
{
    QApplication app(argc, argv);
    QmlApplicationViewer viewer;
    qmlRegisterType<BottomLayer>("Layer", 1, 0, "BottomLayer");
    qmlRegisterType<UpperLayer>("Layer", 1, 0, "UpperLayer");
    viewer.setMainQmlFile(QLatin1String("qml/main.qml"));
    viewer.setViewportUpdateMode(QGraphicsView::MinimalViewportUpdate);
    viewer.showExpanded();
    return app.exec();
}

背景图层(绘制背景图像):

BottomLayer::BottomLayer(QDeclarativeItem *parent) : QDeclarativeItem(parent)
{
    setFlag(QGraphicsItem::ItemHasNoContents, false);
    image.load( "../img.png");
}
void BottomLayer::paint(QPainter* painter,const QStyleOptionGraphicsItem* option, QWidget* widget)
{
    painter->drawImage( QRectF(0, 0, 1920, 1080), image );
}

前景层(绘制线条):

UpperLayer::UpperLayer(QDeclarativeItem *parent) : QDeclarativeItem(parent)
{
    setFlag(QGraphicsItem::ItemHasNoContents, false);
}
void UpperLayer::mousePosCanvasChanged(QPoint pos)
{
    p2 = pos;
    if(drawing)
      update();
}
void UpperLayer::mouseDownCanvasChanged(QPoint pos)
{
    p1 = pos;
    drawing = true;
}
void UpperLayer::mouseUpCanvasChanged(QPoint pos)
{
    drawing = false;
}
void UpperLayer::paint(QPainter* painter, const QStyleOptionGraphicsItem* option, QWidget* widget)
{
    QPen pen(Qt::red, 3, Qt::SolidLine, Qt::RoundCap, Qt::RoundJoin);
    painter->setPen(pen);
    painter->drawLine(p1, p2);
}

QML代码

Rectangle {
  width: 1920
  height: 1080
  color: "transparent"
  MouseArea {
      anchors.fill: parent
      onMousePositionChanged: upper_layer.mousePosCanvasChanged(Qt.point(mouseX,mouseY));
      onPressed: upper_layer.mouseDownCanvasChanged(Qt.point(mouseX,mouseY))
      onReleased: upper_layer.mouseUpCanvasChanged(Qt.point(mouseX,mouseY))
  }
  BottomLayer{
      anchors.fill: parent
  }
  UpperLayer {
      id: upper_layer
      anchors.fill: parent
  }
}

What did I try:

我尝试用viewer.setAttribute(Qt::WA_PaintOnScreen, true)在屏幕上正确地绘制所有内容,这样我就可以避免缓冲开销。这给了我想要的帧率,但一切都变得闪烁。

我想使用背景图像作为缓冲,并在其上进行绘画。考虑到有时我必须自己清理(例如移动屏幕上的项目),这种方法变得过于复杂和不合理。

我试着用图形视图框架这样做,所以我可以限制重绘区域前景项目的剪辑矩形。然而,这并不像期望的那样工作。如果f.ex。我有一条从左上角到右下角的线,clipRectangle覆盖了整个图像(一切又变慢了)。

我尝试计算每个前景项目的clipRectangle并将其传递给update(QRect)update(QRegion)。这给了我与GraphicsViewFramework相同的性能,但是,现在我可以将我的项目分成几个矩形,分别重新绘制每个矩形,并获得更小的重新绘制区域。如果我进一步使用这种方法,我可以逐像素更新每个项目,并完全避免背景重绘。然而,我有一种感觉我做错了什么。如果有可能这样做,Qt中是不是有什么东西可以为我做一切?

注:如果你有其他的想法,我可以试试,我很有兴趣听(读)它们。

如果图像位于所有项目的下方并且不需要移动,您可以在QGraphicsView'::drawBackground()

中绘制它。
相关文章:
  • 没有找到相关文章