Raster in einer QGraphicsScene?

Alles rund um die Programmierung mit Qt
Antworten
mikemc
Beiträge: 42
Registriert: 11. Februar 2009 15:27

Raster in einer QGraphicsScene?

Beitrag 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
franzf
Beiträge: 3114
Registriert: 31. Mai 2006 11:15

Beitrag 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
mikemc
Beiträge: 42
Registriert: 11. Februar 2009 15:27

Beitrag von mikemc »

Danke, das ist schon mal ein guter Hinweis!

Schade, dass es nicht eine eingebaute Rasterfunktion in der Scene gibt ;)
VuuRWerK
Beiträge: 82
Registriert: 11. Juni 2007 20:46
Wohnort: Dresden

Beitrag 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 ;)
Es gibt nur 3 natürliche Feinde des Programmierers: Tageslicht, frische Luft und das unerträgliche Gebrüll der Vögel.
Oft ist die Ursache des schwarzsehens lediglich ein verrutschen des Bretts vorm Kopf =)
griffin27
Beiträge: 12
Registriert: 13. Februar 2009 15:20

Raster Punkte in einer QGraphicsScene darstellen

Beitrag 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
franzf
Beiträge: 3114
Registriert: 31. Mai 2006 11:15

Beitrag 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
upsala
Beiträge: 3946
Registriert: 5. Februar 2006 20:52
Wohnort: Landshut
Kontaktdaten:

Beitrag von upsala »

Oder man verwendet drawBackground()
griffin27
Beiträge: 12
Registriert: 13. Februar 2009 15:20

Beitrag 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]
mikemc
Beiträge: 42
Registriert: 11. Februar 2009 15:27

Beitrag 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?
upsala
Beiträge: 3946
Registriert: 5. Februar 2006 20:52
Wohnort: Landshut
Kontaktdaten:

Beitrag von upsala »

Du beachtest aber schon deinen rect-Parameter?
mikemc
Beiträge: 42
Registriert: 11. Februar 2009 15:27

Beitrag von mikemc »

nur den RECT-Bereich zu berücksichtigen bringt nur minimale Beschleunigung, was aber echt geholfen hat war dieser Befehl: "setCacheMode ( ItemCoordinateCache )"
VuuRWerK
Beiträge: 82
Registriert: 11. Juni 2007 20:46
Wohnort: Dresden

Beitrag 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 ;)
Es gibt nur 3 natürliche Feinde des Programmierers: Tageslicht, frische Luft und das unerträgliche Gebrüll der Vögel.
Oft ist die Ursache des schwarzsehens lediglich ein verrutschen des Bretts vorm Kopf =)
mikemc
Beiträge: 42
Registriert: 11. Februar 2009 15:27

Beitrag 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?
Antworten