QPainter Zeichenobjekte identifizieren bei Klick ?!

Alles rund um die Programmierung mit Qt
Antworten
wojtek85
Beiträge: 37
Registriert: 11. Mai 2007 19:56
Wohnort: Köln
Kontaktdaten:

QPainter Zeichenobjekte identifizieren bei Klick ?!

Beitrag von wojtek85 »

Hallo,

ich stelle in einem Tool auf einer Zeichenoberflaeche (QPixmap auf QLabel) Graphen dar. Diese Graphen bzw. die Knoten (QPainter.drawPoint()) und Kanten (QPainter.drawLine()) enthalten diverse Informationen die ich bei Klick auf Knoten/Kante in einem kleinen Popup anzeigen will.

Ich habe bereits einmal mit OpenGL gearbeitet, da war das sehr bequem da ich die vorher vergebenen "Namen" der getroffenen Objekte bei einem Mausklick bekommen habe und somit direkt identifizieren konnte um welches Objekt es sich handelt. Nun wollte ich wissen ob es sowas Aehnliches auch bei Qt gibt. Meine Idee dazu ist bisher die Koordinaten des Klicks abzufangen und meine Knoten und Kanten zu durchlaufen um zu sehen ob etwas davon "erwischt" wurde.

Kennt jemand ein eleganteres Prinzip bzw. weiss jemand etwas wie man am besten QPainter-Objekte identifiziert??

Vielen Dank.
Gruss, Wojtek
CaptnChaos
Beiträge: 605
Registriert: 28. Juni 2007 15:01
Kontaktdaten:

Beitrag von CaptnChaos »

Erstelle für jedes Objekt ein QRect. dann kannst du QRect.contains(QPoint point) abfragen.
wojtek85
Beiträge: 37
Registriert: 11. Mai 2007 19:56
Wohnort: Köln
Kontaktdaten:

Beitrag von wojtek85 »

Ok, fuer die Knoten leuchtet mir das ein (abgesehen davon das diese rund sind), aber fuer die Kanten macht das doch keinen Sinn. Angenommen ich hab eine Kante von (0,0) nach (max,max), d.h. ich meusste fuer diese Kante ein QRect ueber die ganze Zeichenflaeche zeichnen, dann kann ich klicken was ich will und der Punkt ist im Rect enthalten!?
CaptnChaos
Beiträge: 605
Registriert: 28. Juni 2007 15:01
Kontaktdaten:

Beitrag von CaptnChaos »

nimm dafür ein QRegion. Dort fügst du zwei QRects ein. Das eine Rect für die waagerechte linie, das andere für die senkrechte.

|
| } QRegion region(0,0,1,3);
|_____ } region.united(QRect(0,3,3,1));
upsala
Beiträge: 3946
Registriert: 5. Februar 2006 20:52
Wohnort: Landshut
Kontaktdaten:

Beitrag von upsala »

QGraphicsView wäre event. auch ein passender Ansatz
wojtek85
Beiträge: 37
Registriert: 11. Mai 2007 19:56
Wohnort: Köln
Kontaktdaten:

Beitrag von wojtek85 »

Also das mit den beiden QRects wird wohl auch nicht gehen, da die Kanten nicht geknickt sind und in einem beliebigen Winkel ueber die Zeichenflaeche verlaufen. Ein Graph koennte bspw. so aussehen wie angehaengt.
Dateianhänge
002_dual.png
002_dual.png (90.93 KiB) 7785 mal betrachtet
CaptnChaos
Beiträge: 605
Registriert: 28. Juni 2007 15:01
Kontaktdaten:

Beitrag von CaptnChaos »

also willst du jetzt die linien verschieben? oder die punkte? du könntest auch qpainterpath benutzen. der unterstützt alles und kann ebenfalls contains abfrage.
wojtek85
Beiträge: 37
Registriert: 11. Mai 2007 19:56
Wohnort: Köln
Kontaktdaten:

Beitrag von wojtek85 »

Nein, also was moeglich sein soll, ist Folgendes: angenommen der Beispielgraph waere geladen, dann wuerde ich gerne auf die Zeichenflaeche klicken und wissen ob und wenn ja welcher Knoten/welche Kante erwischt wurde. Das koennte ich natuerlich per Hand machen indem ich x und y Korrdinaten des Klicks mit den Daten der Knoten/Kanten vergleiche, aber das ist mir zu aufwaendig, suche nach einer besseren Loesung, falls sowas von Qt unterstuetzt wird.
upsala
Beiträge: 3946
Registriert: 5. Februar 2006 20:52
Wohnort: Landshut
Kontaktdaten:

Beitrag von upsala »

Wie gesagt: QGraphicsView.
wojtek85
Beiträge: 37
Registriert: 11. Mai 2007 19:56
Wohnort: Köln
Kontaktdaten:

Beitrag von wojtek85 »

Danke erstmal, das mit dem GraphicsView klappt wunderbar und ist dazu noch schneller. Nur ich habe da noch ein kleines Probleme. Fuege meiner GraphicsScene eigene Objekte (einmal abgeleitet von QGraphicsLineItem und einmal von QGraphicsEllipseItem) hinzu, jedoch fehlt mir da die Option das ich Pen bzw. Pen und Brush angeben kann, wenn ich addItem() mache. Mit addEllipse() und addLine() geht das natuerlich einfach, aber fuer meine eigenen abgeleiteten Objekte finde ich keine Option (auch nicht in der Doku :oops:). Hat jemand eine Idee?

Danke, Wojtek
wojtek85
Beiträge: 37
Registriert: 11. Mai 2007 19:56
Wohnort: Köln
Kontaktdaten:

Beitrag von wojtek85 »

Ohh, da hab ich wohl nicht ordentlich geguckt...
Hab nun noch eine andere Frage. Bei gefärbten Graphen ist mir aufgefallen das teilweise Linien oberhalb der Kreise verlaufen und andere unterhalb (Linien starten immer in den Mittelpunkten der Kreise). Meine Zeichenroutine durchläuft aber erst alle Linien, danach alle Kreise, d.h. diese müssten über den Linien liegen. Das war bei Benutzung von QPainter auch immer so.
Eine andere Frage betrifft nochmal das Identifizieren nach Klick. Kann mit itemAt(event->scenePos()) ein QGraphicsItem zurückbekommen. So weit super, aber wie sieht es aus wenn ich meinen eigene Objekte Edge abgeleitet von QGraphicsLineItem und Node abgeleitet von QGraphicsEllipseItem zurückbekommen möchte. Da fehlt mir irgendwie der Ansatz. Wobei QGraphics_x_Item von QGraphicsItem abgeleitet ist, d.h. meine Objekte müssten doch auch als QGraphicsItem akzeptiert werden, oder nicht? Das klappt ja auch wenn ich sage scene->addItem(meinAbgeleitetetesObjekt). Danke für Eure Hilfe!

Gruss, Wojtek
Antworten