2016-10-11 8 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); 
} 

Foreground слой (рисование линий):

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()

 Смежные вопросы

  • Нет связанных вопросов^_^