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.私が試してみることができる他のアイデアがあるなら、私はそれらを聞くことに興味があります。