Seite 1 von 1

Kopierkonstruktor bei einer QGraphicsRectItem Klasse

Verfasst: 16. September 2010 12:47
von anno1988
Hallo,

ich habe mir eine QGraphicsRectItem Klasse abgeleitet und darin ein QGraphicsSvgItem eingebettet, zusammen mit einem Kopierkonstruktor.

Code: Alles auswählen


class Myrect : public QObject, public QGraphicsRectItem {

	Q_OBJECT

	private:
		QGraphicsSvgItem *my_svg;

	protected:		

	public:		
		Myrect(QString fileName, QGraphicsItem *parent = 0);
		Myrect(const Myrect &item);
		void setRect(qreal x, qreal y, qreal w, qreal h);

};


	Myrect(QString fileName, QGraphicsItem *parent = 0) {

		my_svg = new QGraphicsSvgItem(fileName);

	}


	Myrect::Myrect(const Myrect &item) {



	}



	void Myrect::setRect(qreal x, qreal y, qreal w, qreal h) {

		QGraphicsRectItem::setRect(x, y, w, h);

		my_svg->setPos(x, y);

	}

Wenn ich das Objekt nun kopieren will, wird mir beim neuen Objekt nie eine Kopie des "my_svg" Objekts erstellt. Weiß da jemand wieso? Genau so verhält es sich mit den Koordinaten die angelegt wurden mit der "setRect()" Methode oder wenn ich in der "my_new_rect0" Klasse "setBrush()" setzen. das wird auch nicht mit kopiert.

Code: Alles auswählen


Myrect *my_new_rect0;

my_new_rect0 = new Myrect("/der/pfad/zur/datei.svg");
my_new_rect0->setRect(50, 50, 300, 300);


Myrect *my_new_rect1;

my_new_rect1 = new Myrect(*my_new_rect0);
my_new_rect1->setRect(50, 50, 300, 300);

Weiß da jemand wie ich das hin bekomme ?

Verfasst: 16. September 2010 13:46
von franzf
QGraphicsItem hat keinen Kopierkonstruktor. Wenn du also Daten kopieren willst, musst du das alles selber machen - auch für alle Properties der Basisklasse(n)! Außerdem fehlt dir für ordentliches Verhalten noch der operator=
Dass dein my_svg nie kopiert wird, sollte auch klar sein: Das ist ein Pointer! Der Wert eines Pointers ist die Adresse des Objektes auf das er zeigt. Kopien beziehen sich auf den "Wert" (oder State) des Objektes. Bei einem Pointer erhält der neue einfach den Wert des Alten Pointers, zeigt also auf das selbe Objekt. Und genau hier wird es für dich jetzt richtig doof - QGraphicsSvgItem hat ebenfalls keinen Kopierkonstruktor! Wenn du eine Kopie dieses SvgItems ziehen willst, musst du ein neues SvgItem anlegen und alle relevanten Daten rüberkopieren. (Frage: Was machst du mit einem evtl. existierenden SharedRenderer? Verlässt du dich darauf, dass der deine Kopie überlebt? Setzt du einen neuen?

Lösung: QGraphicsItems sind nicht zum Kopieren gedacht! Es gibt einfach zu viele Probleme, die nicht eindeutig gelöst werden können: Was soll kopiert werden? Was passiert mit childItems? Was mache ich mit gesetzten Transformationen? Da Qt für all das keine Standardlösung definieren wollte, wurde Kopiersemantik nicht umgesetzt.

Wenn du also deine Items "Kopieren" willst, stell eine clone()-Funktion zur Verfügung:

Code: Alles auswählen

class RectItem : public QGraphicsRectItem {
  // Daten, usw.
public:
  // gibt einen Klon des aktuellen Objekts zurück
  RectItem* clone() const;
};

// Anwendung:
RectItem* rect = new RectItem;
RectItem* kopie = rect->clone();

Verfasst: 16. September 2010 14:30
von anno1988
ok thx für die Hilfe.

So was habe ich mir schon gedacht, dass ich da keinen Kopierkonstruktor nehmen kann. Dann erstelle ich in der clone() Methode einfach ein neues "Myrect" objekt und gebe davon dann den zeiger des neuen objekts aus, so wie in deinem beispiel.