2016-10-11 2 views
0

Sagen wir, wir haben 2 qDeclarativeItem ist übereinander gelegt. Der untere Eintrag enthält ein Hintergrundbild (die meiste Zeit bleibt unverändert). Das oberste Element enthält eine Reihe einfacher Elemente (Linien, Bögen usw.), die direkt mit der Maus bearbeitet werden können.Schnelle Zeichnung auf einem qDeclarativeItem

Problem: Wenn Sie auf der oberen Schicht malen, ist auch die untere Schicht vollständig überstrichen. Wenn man bedenkt, dass ich dort ein großes Bild habe, ist es sehr langsam neu zu streichen.

Als Beispiel für oben genannten, hier ist ein Code.

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

Hintergrundebene (Malerei das Hintergrundbild):

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); 
} 

Vordergrund Schicht (Zeichnen von Linien):

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-Code

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 
    } 
} 

Was habe ich versuchen, :

Ich habe versucht, alles auf dem Bildschirm mit viewer.setAttribute(Qt::WA_PaintOnScreen, true) zu malen, so dass ich Puffer vermeiden kann. Dies gibt mir die gewünschte Bildrate, aber alles wird flickerig.

Ich dachte daran, das Hintergrundbild als Puffer zu verwenden und die Malerei direkt darauf zu machen. Wenn man bedenkt, dass ich manchmal nach mir selbst putzen muss (z. B. den Gegenstand auf dem Bildschirm bewegen), wird dieser Ansatz zu komplex und ungerechtfertigt.

Ich habe es mit Graphics View Framework versucht, so dass ich den Repaint-Bereich auf das Clip-Rechteck des Vordergrundelements beschränken kann. Dies funktioniert jedoch nicht wie gewünscht. Wenn z. Ich habe eine Linie von oben links nach unten rechts, der ClipRectangle bedeckt das ganze Bild (alles ist wieder langsam).

Ich habe versucht, den ClipRectangle für jedes Vordergrundelement zu berechnen und es an update(QRect) und update(QRegion) zu übergeben. Dies gibt mir die gleiche Leistung wie GraphicsViewFramework, aber jetzt kann ich meine Elemente in mehrere Rechtecke aufteilen, sie jeweils separat streichen und einen noch kleineren Repaint-Bereich erhalten. Wenn ich diesen Ansatz weiterführe, kann ich jedes Element pixelweise aktualisieren und Hintergrundüberstreichungen vermeiden. Ich habe jedoch das Gefühl, dass ich etwas falsch mache. Wenn es möglich ist, dies zu tun, gibt es nicht etwas in Qt, das alles für mich tun kann?

P.S. Wenn Sie andere Ideen haben, die ich ausprobieren kann, bin ich daran interessiert, sie zu hören (zu lesen).

Antwort

0

Wenn das Bild unter allen Elementen liegt und nicht verschoben werden muss, können Sie es wahrscheinlich in QGraphicsView'::drawBackground()

zeichnen