2016-10-11 47 views
0

假設我們有2個qDeclarativeItem放在彼此的頂部。底部項目包含背景圖像(大部分時間保持不變)。頂部項目包含一些簡單的項目(直線,弧線......),可以使用鼠標直接編輯。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來做,所以我可以限制重繪區域到前景項目的剪輯矩形。然而,這不符合要求。如果f.ex.我有一條從左上角到右下角的線,clipRectangle覆蓋整個圖像(一切都很慢)。

我試着計算每個前景項目的clipRectangle並將它傳遞到update(QRect)update(QRegion)。這給了我與GraphicsViewFramework相同的性能,但現在我可以將我的項目分成幾個矩形,分別重新繪製每個項目並獲得更小的重繪區域。如果我進一步採用這種方法,我可以逐個像素地更新每個項目,並且完全避免背景重繪。但是,我有一種感覺,我做錯了什麼。如果可以這樣做,Qt中沒有什麼能爲我做的一切嗎?

P.S.如果你有其他想法可以嘗試,我很樂意聽到(閱讀)它們。

回答

0

如果圖像低於所有項目並且不需要移動,則可以將其繪製在QGraphicsView'::drawBackground()