ich bin derzeit dabei, eine Art Schaltplan-Editor in Qt zu programmieren. Das mache ich mit einer QGraphicsScene. Ich habe mir mehrere eigene Klassen, die von QGraphicsItem abstammen, abgeleitet, die die entsprechenden Elemente darstellen. So zum Beispiel einen Resistor.
Die Elemente lassen sich bisher ohne Probleme platzieren. Nun möchte ich Verbindungsleitungen programmieren, was auch soweit schon funktioniert. Um diese Verbindungen jedoch genau platzieren zu können, möchte ich eine Art Fang implementieren, also eine Funktion, wenn man in der Nähe eines Anschlusses des entsprechenden Elements klickt um die Verbindung zu platzieren, die Leitung direkt am Anschluss platziert wird.
Dazu hab ich dem Gebiet, dass dem GraphicsItem angehört zwei Rechtecke zugewiesen (um die Anschlusspunkte herum). Klickt man nun, so überprüft QGraphicsScene, ob sich die Maus an einem Element befindet. Ist dies der Fall, soll eine Methode des entsprechenden Items aufgerufen werden, die überprüft in welchem der beiden Rechtecke sich der angeklickte Punkt befindet und gibt dann den Punkt zurück, der dem entsprechenden Anschluss entspricht.
Das Ganze sieht so aus, am Beispiel des Elementes Resistor:
Deklaration der Klasse
Code: Alles auswählen
class ElementResistor : public QGraphicsItem
{
public:
ElementResistor();
QRectF boundingRect() const;
void paint ( QPainter *painter,
const QStyleOptionGraphicsItem *option,
QWidget *widget );
enum { Type = UserType + 1 };
int type() const
{
// Enable the use of qgraphicsitem_cast with this item.
return Type;
}
private:
QRectF rectNodeA;
QRectF rectNodeB;
QPoint pointNodeA;
QPoint pointNodeB;
void setRects();
void setNodes();
public:
QPointF assignPoint( QPointF );
};
Code: Alles auswählen
//Methode zur Überprüfung, in welchem Rechteck sich der Übergabewert befindet
QPointF ElementResistor::assignPoint(QPointF thisPoint)
{
//Punkt in Koordinatensystem des Elements umrechnen
thisPoint = mapFromScene(thisPoint.x(), thisPoint.y() );
//Wenn sich Punkt im Rechteck des Knoten A befindet
if( rectNodeA.contains( thisPoint ) )
{
//den in Scene-Koordinaten umgerechneten Punkt von Knoten A zurückgeben
return mapToScene( pointNodeA.x(), pointNodeA.y() );
}
//ansonsten befindet sich Punkt im Rechteck von Knoten B
if( rectNodeB.contains( thisPoint) )
{
//und der Punkt von Knoten B wird zurückgegeben
return mapToScene( pointNodeB.x(), pointNodeB.y() );
}
}
Code: Alles auswählen
//Wenn der angeklickte Punkt auf einem Scene-Item befindet
if ( scene->itemAt( mapToSceneWithGrid( event->x(), event->y() )))
{
//Pointer des entsprechenden Items in ItemA einlesen
ItemA = scene->itemAt( mapToSceneWithGrid(event->x(), event->y()));
//und den Pointer von QGraphicsItem* zu ElementResistor* casten
ElementResistor *actualResistor = qgraphicsitem_cast<ElementResistor*>(ItemA);
//und die Methode zum Zuweisen des Punktes des Elements aufrufen
pointA = actualResistor->assignPoint( pointA );
}
Ich habe jetzt zwei Resistors platziert. Ich wähle die Funktion zum Platzierung einer Verbindung aus und klicke in den Bereich eines Knotens von Resistor1. Alles verläuft soi gewünscht, die Verbindung wird direkt am Anschluss angebracht. Klicke ich jedoch, um die Verbindung zu vervollständigen den zweiten Resistor an, erhalt ich einen Laufzeitfehler. Klicke ich in einen freien Bereich, in dem diese if-Anweisung nicht ausgeführt wird, stürzt das Programm nicht ab.
Es muss also was mit dem Aufruf der Methode nicht funktionieren. Ich nehme stark an, dass es etwas mit diesem Code-Abschnitt zu tun hat:
Code: Alles auswählen
enum { Type = UserType + 1 };
int type() const
{
// Enable the use of qgraphicsitem_cast with this item.
return Type;
}
Kann mir hierbei irgendjemand helfen, das Problem zu lösen?
MfG und Danke