2016-10-11 10 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()

関連する問題