Seite 1 von 1

Raster in einer QGraphicsScene?

Verfasst: 11. Februar 2009 15:54
von mikemc
Grüss euch!

Ich würde gerne QGraphicsItem's in einer QGraphicsScene nur auf einem bestimmten Raster zulassen, d.h. die Items sollten sich bei Verschieben nur z.B. alle 5 Pixel einrasten lassen.

Habt ihr einen Tipp für mich?

Grüsse aus Österreich

Michi

Verfasst: 11. Februar 2009 16:04
von franzf
Du könntest eine eigene Basisklasse für deine ganzen Items (abgeleitet von QGraphicsItem) erstellen, in der du mit den mouse***Event()s spielst, und das event nur die neue Position setzt, wenn die neue X-/Y-Position um 5 PX von der alten entfernt ist.

Alternaitv gibts die gleichen Events auch in QGraphicsScene. Da musst du dir halt zusätzlich zum aktuellen state noch das zu verschiebende item merken. Ist aber eh nur ein Pointer.

Wenn du das ganze über die Scene implementierst, kannst du leichter die Rasterweite ändern.

Grüße
Franz

Verfasst: 11. Februar 2009 17:53
von mikemc
Danke, das ist schon mal ein guter Hinweis!

Schade, dass es nicht eine eingebaute Rasterfunktion in der Scene gibt ;)

Verfasst: 11. Februar 2009 21:19
von VuuRWerK
Du kannst QGraphicsScene#dragMoveEvent überschreiben und dann via QGraphicsScene#selectedItems die Items ermitteln die gerade bewegt werden und entsprechend ausrichten.

Gujt Schuß
VuuRWerK ;)

Raster Punkte in einer QGraphicsScene darstellen

Verfasst: 13. Februar 2009 16:02
von griffin27
Hallo,

ich muss mich kurz dem Thema anschließen.

Wie würdet ihr Rasterpunkte darstellen?
Hab da grad gar keinen Plan. Denn die Punkte sollen ja immer genau ein Pixel groß sein, und nicht unterschiedlich groß werden beim Zoomen.

Vorallem soll das dann auch noch richtig schnell sein. Kurz über schlagen werden bis zu 20.000 Punkte dargestellt.

lg, griffin

Verfasst: 13. Februar 2009 16:13
von franzf
Graphics View ist prinzipiell ziemlich schnell (-> chips demo).
Ansonsten kannst du
1) ein eigenes Item über/unter alle anderen Items legen, und dieses beim Zoomen speziell behandeln, so dass es immer gleich groß erscheint.
2) Wenn dir das (sichtbare) Raster im Hintergrund reicht, kannst du mittels setViewport() ein eigenes Raster-Widget als Viewport setzen. Auf diesem wird dann gezeichnet. (Hoffe ich, hab ich noch nicht ausprobiert :D)

Grüße
Franz

Verfasst: 13. Februar 2009 16:27
von upsala
Oder man verwendet drawBackground()

Verfasst: 17. Februar 2009 11:04
von griffin27
Ich hab jetzt einfach ein Item erstellt, das in der paint Methode die Rasterpunkte mit drawPoint zeichnet.

Code: Alles auswählen

class GridItem : public QGraphicsItem{
...
}

Code: Alles auswählen

void GridItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
{
    painter->setPen(Qt::white);
    for(qreal y=rect.y(); y<=rect.height(); y+=grid){
        for(qreal x=rect.x(); x<rect.width(); x+=grid){
            painter->drawPoint(qRound(x),qRound(y));
        }
    }
}
Seltsamerweise sind die Punkte immer genau ein Pixel groß.
Anti-Aliasing hab ich nicht aktiviert, damit die Punkte nicht verschwommen dargestellt werden. [/code]

Verfasst: 19. Februar 2009 12:45
von mikemc
Bin auch gerade am Versuchen Punkte darzustellen.

Den Versuch in der Background-Funktion der GraphicScene 2 For-Schleifen einzubauen kann ich mir abschminken, da das Verschieben von Items sehr langsam ist.

Ein eigenes Grid-Item bringt auch kaum verbesserung, auch da wird jedesmal die gesamte Vorschleife durchgegangen wenn ein Objekt verschoben wird.

Gibt es da bessere Lösungsvarianten?

Verfasst: 19. Februar 2009 16:54
von upsala
Du beachtest aber schon deinen rect-Parameter?

Verfasst: 23. Februar 2009 13:19
von mikemc
nur den RECT-Bereich zu berücksichtigen bringt nur minimale Beschleunigung, was aber echt geholfen hat war dieser Befehl: "setCacheMode ( ItemCoordinateCache )"

Verfasst: 23. Februar 2009 16:56
von VuuRWerK
Auch schonmal QGraphicsView#backgroundBrush-Property in Verbindung mit BrushStyle angeschaut? Eventuell schauen ob man selber einen solchen BrushStyle implementieren kann und damit den Hintergrund zeichen lassen, geht denke ich mal um einiges fixer als selber die Linien übers komplette View zu zeichen? Nur so ein Gedanke. Denke wenn man zoomen will siehts schon wieder anders aus ...

Gut Schuß
VuuRWerK ;)

Verfasst: 23. Februar 2009 19:09
von mikemc
Ok das werde ich auch mal probieren.

Habe jetzt die Variante mit mouseMoveEvent() abfangen ausprobiert. Das funktioniert prima solange man ein einzelnes Item bewegt. Sobald man aber mehrere Items selektiert, bewegt sich das Item unter dem Mauspfeil von Raster zu Raster, während sich die restlichen Items noch immer flüssig bewegen weil ich natürlich mouseMoveEvent von der Basisklasse auch ausführen lasse.

Am liebsten würde ich die setPos() Funktion überschreiben, die wird aber nur von meiner abgeleiteten Klasse verwendet, jedoch verwendet die Basisfunktion mouseMoveEvent() von QGraphicsItem nicht meine überschriebene Funktion setPos().

Was kann ich tun, ohne auf den ganzen automatischen Mechanismus von Items selektieren und gemeinesam verschieben selber ausprogrammieren zu müssen?