2009-08-31 2 views
8

Ich habe mir stundenlang die Haare ausgezogen. Es gibt einen Thread here darüber, aber nichts scheint zu funktionieren. QGraphicsView :: rect() gibt die Breite und Höhe zurück, aber die left und Werte sind nicht richtig eingestellt (immer 0 - ignoriert den gescrollten Betrag). Ich möchte es in Szene-Koordinaten, aber es sollte leicht genug sein, um von jedem System zu übersetzen. Ich habe keine Ahnung, was horizontalScrollBar()->value() und Vert zurückkehren ... scheint sinnlos Jibberish zu sein.Erhalten Sie ein sichtbares Rechteck von QGraphicsView?


@fabrizioM:

// created here 
void EditorWindow::createScene() { 
    m_scene = new EditorScene(this); 
    m_view = new EditorView(m_scene); 
    setCentralWidget(m_view); 
    connect(m_scene, SIGNAL(mousePosChanged(QPointF)), this, SLOT(mousePosChanged(QPointF))); 
} 

/// with this constructor 
EditorView::EditorView(QGraphicsScene* scene, QWidget* parent) : QGraphicsView(scene, parent) { 
    setRenderHint(QPainter::Antialiasing); 
    setCacheMode(QGraphicsView::CacheBackground); 
    setViewportUpdateMode(QGraphicsView::FullViewportUpdate); 
    setDragMode(QGraphicsView::NoDrag); 
    scale(1.0, -1.0); // flip coordinate system so that y increases upwards 
    fitInView(-5, -5, 10, 10, Qt::KeepAspectRatio); 
    setInteractive(true); 
    setBackgroundBrush(QBrush(QColor(232,232,232), Qt::DiagCrossPattern)); 
} 
+0

Scratch, dass ... die Scrollbar-Werte sind relativ zu ... Nun, es kann nicht die SzeneRect() sein, denn das sind Schwimmer ... aber etwas ähnliches. – mpen

+0

Vielleicht ist, wie Sie die QGraphicsView, irgendein Quellcode-Snippet konstruieren? – fabrizioM

+0

Ich bin mir nicht sicher, welchen Code Sie genau wollen. Es ist nicht wirklich wichtig, wie ich es konstruiere ... das sichtbare Rect zu bekommen sollte genau das gleiche sein. – mpen

Antwort

3

Nevermind. Kam damit auf, was zu funktionieren scheint.

QRectF EditorView::visibleRect() { 
    QPointF tl(horizontalScrollBar()->value(), verticalScrollBar()->value()); 
    QPointF br = tl + viewport()->rect().bottomRight(); 
    QMatrix mat = matrix().inverted(); 
    return mat.mapRect(QRectF(tl,br)); 
} 
+1

Trotzdem hat mir deine Antwort sehr geholfen. Vielen Dank! – Eike

1

Es klingt wie, was Sie wollen, ist die Szene Rechteck. Die ::rect()-Methode wird von QWidget geerbt. Siehe:

http://doc.qt.io/qt-5/qgraphicsview.html#sceneRect-prop

+0

Haben Sie die Beschreibung gelesen? "Das Szenenrechteck definiert die Ausdehnung der Szene und im Ansichtsfall den Bereich der Szene, in dem Sie mithilfe der Bildlaufleisten navigieren können." sceneRect gibt die * gesamte * Szene zurück, nicht nur den aktuell sichtbaren Bereich (einen Teilbereich der Szene). – mpen

+0

Direkt aus der Dokumentation herausgeholt; "Diese Eigenschaft enthält den Bereich der Szene, der durch diese Ansicht visualisiert wird." Das ist was du willst, oder? Sie können auch mapTo und mapFrom verwenden, um zwischen Koordinatensystemen zu konvertieren. –

+0

Die Dokumente sind nicht klar. Was bedeutet "visualisiert"? Bedeutet es den Bereich der Szene, mit dem du arbeitest oder was gerade gezeichnet wird? Wenn Sie eine riesige Szene haben, in der Sie herumrollen können, ist diese Wortwahl mehrdeutig. Ich war auch verwirrt. es sieht so aus, als wäre das die ganze Szene, nicht nur der Bereich, den du gerade in der Ansicht sehen kannst. – Rafe

2

Sie können tun, was Sie getan haben, oder verwenden Sie die mapToScene() Funktionen. Sie können jedoch nicht davon ausgehen, dass das Rechteck der Szene "rectangle" ein Rechteck ist, da die Szene in der Ansicht gedreht oder geschert werden könnte, was bei der Zuordnung zur Szene zu einem allgemeinen Polygon führt.

Wenn Ihre Anwendung solche Dinge nie tut, können Sie natürlich davon ausgehen, dass ein Rechteck immer angemessen ist.

+0

Karte * was * zur Szene obwohl? Ich kann die Informationen, die ich brauche, nicht von anderen als den Bildlaufleisten bekommen. – mpen

3

hier ist eine mögliche Lösung (keine Ahnung, ob dies der einzige beabsichtigt ist)

QRectF XXX::getCurrrentlyVisibleRegion() const 
{ 
     //to receive the currently visible area, map the widgets bounds to the scene 

     QPointF topLeft = mapToScene (0, 0); 
     QPointF bottomRight = mapToScene (this->width(), this->height()); 

     return QRectF (topLeft, bottomRight); 
} 

HTH, Bernhard

+0

In Qt 4.7.4 funktionieren die meisten Antworten hier nicht. Die Ansichtskoordinaten (0, 0) scheinen nicht immer oben links im sichtbaren Bereich zu liegen. Stattdessen wird das Ansichtskoordinatensystem selbst durch die Bildlaufleisten verschoben. Aber Marks Methode funktioniert! (für mich) – Eike

16

Karte einfach die pixelbasierte Bildfenster Rechteck in der Szene die Ansicht mit:

graphicsView->mapToScene(graphicsView->viewport()->geometry()).boundingRect() 

Bye, Marcel

+4

Könnte kürzer sein, um 'graphicsView-> rect()' anstelle von 'graphicsView-> viewport() -> geometry()' zu verwenden. – Sharpie

3

Die folgende Umsetzung die besten Ergebnisse für mich zurück:

QRectF getVisibleRect(QGraphicsView * view) 
{ 
    QPointF A = view ->mapToScene(QPointF(0,0)), 
    QPointF B = view ->mapToScene(QPointF( 
     view->viewport()->width(), 
     view->viewport()->height()); 
    return QRectF(A, B); 
} 

Das funktioniert immer noch sehr gut, wenn Bildlaufleisten angezeigt. Dies funktioniert nur dann ordnungsgemäß, wenn die Szene nicht gedreht oder geschert dargestellt wird. Wenn die Ansicht gedreht oder geschert wird, ist das sichtbare Rechteck im Szenen-Koordinatensystem nicht achsparallel. In diesem Fall

view->mapToScene(view->viewport()->geometry()) 

gibt ein QPolygonF (NOT a QRectF), die das sichtbare Rechteck ist in Szene Koordinaten. Übrigens, QPolygonF hat eine Elementfunktion boundingRect(), die nicht das richtige sichtbare Rechteck der Ansicht zurückgibt, aber trotzdem nützlich sein könnte.

+0

Das von Ihnen bereitgestellte Codebeispiel enthält viele Fehler! – ForeverLearning