[英]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.