簡體   English   中英

快速繪制qDeclarativeItem

[英]Fast drawing on a qDeclarativeItem

假設我們有2個qDeclarativeItem彼此疊加。 底部項目包含背景圖像(大多數時間保持不變)。 頂部項目包含一堆簡單的項目(直線,圓弧...),可以使用鼠標直接對其進行編輯。

問題:在頂層繪畫時,buttom層也被完全重新繪畫。 考慮到我那里的圖像很大,因此重新粉刷非常慢。

作為上述示例,下面是一些代碼。

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
  }
}

我嘗試了什么:

我嘗試使用viewer.setAttribute(Qt::WA_PaintOnScreen, true)在屏幕上正確繪制所有內容,因此可以避免緩沖開銷。 這給了我想要的幀速率,但是一切都變得忽悠。

我考慮過使用背景圖像作為緩沖區並在其上進行繪畫。 考慮到有時我必須自己清理(例如,移動屏幕上的項目),這種方法變得過於復雜和不合理。

我嘗試使用Graphics View Framework進行此操作,因此可以將重繪區域限制為前景項目的剪輯矩形。 但是,這不能按需工作。 如果是 我有一條線從左上角到右下角,clipRectangle覆蓋了整個圖像(一切都變慢了)。

我嘗試為每個前景項目計算clipRectangle並將其傳遞給update(QRect)update(QRegion) 這給了我與GraphicsViewFramework相同的性能,但是,現在我可以將項目划分為幾個矩形,分別重新粉刷一個,並獲得一個更小的粉刷區域。 如果我進一步采用這種方法,則可以逐像素更新每個項目,並且完全避免重新繪制背景。 但是,我感覺自己做錯了。 如果有可能這樣做,那么Qt中是否可以為我做任何事情?

PS:如果您有其他可以嘗試的想法,我很想聽聽(閱讀)它們。

如果圖像在所有項目下面並且不需要移動,則可以在QGraphicsView'::drawBackground()繪制它

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM