Kleine Hilfestellung für uns bei Drag&Drop in einem Tree

Alles rund um die Programmierung mit Qt
Antworten
buhrmi
Beiträge: 18
Registriert: 21. Oktober 2006 14:43
Kontaktdaten:

Kleine Hilfestellung für uns bei Drag&Drop in einem Tree

Beitrag von buhrmi »

Hallo alle,

ich hoffe jemand hat Zeit uns bei dem etwas größeren Problem zu helfen ^^ Eigentlich ist es nicht wirklich ein Problem, eher ein Fall von totaler Planlosigkeit... Also:

In unserm Projekt haben wir eine Datenstruktur mit einem QAbstractItemModel und ein paar hierarisch eingeordnete Items, die wir in einem TreeView anzeigen. Das klappt gut. Nun müssen wir Drag&Drop implementieren, so dass am Ende - je nach Möglichkeit - folgendes Möglich ist:

1.: Ein beliebiges Item auf ein anderes Item ziehen, und dieses wird dann ein Kind von dem anderen Item.
2.: Ein beliebiges Item zwischen zwei andere Items ziehen, und dieses bekommt dann den selben Elternknoten wie das obere Item.

Wir haben uns schon viel durchgelesen und Beispiele angeschaut, allerdings noch keinen konkreten Plan, wo wir bei diesem Vorhaben ansetzen müssen. Ist das was wir wollen denn machbar? Ich nehme an, wir müssen uns eine Klasse von QAbstractItemModel ableiten... Doch welche Funktionen müssen überschrieben werden? Solche Fragen schwirren momentan in unseren Köpfen herum.

Falls uns jemand einen Stoß in die richtige Richtung geben mag, einige Sachen nennen möchte, die wichtig sind, oder uns ein "AHA-Erlebnis" bescheren mag, dann nur zu ;))

Lieben Gruß,
buhrmi
upsala
Beiträge: 3946
Registriert: 5. Februar 2006 20:52
Wohnort: Landshut
Kontaktdaten:

Beitrag von upsala »

Das schon mal durchgelesen? Drag and Drop
buhrmi
Beiträge: 18
Registriert: 21. Oktober 2006 14:43
Kontaktdaten:

Beitrag von buhrmi »

Hi,

danke der Link hat uns sehr weitergeholfen, das war recht einfach hinzukriegen.

Aber nun haben wir folgendes Problem:
Ursprünglich hatten wir Klassen, welche von QStandardItem geerbt haben in dem ItemModel verwendet. Doch durch das Draggen und Droppen werden (so haben wir herausgefunden, korrigiert mich wenn es nicht stimmt) die Einträge im Model nicht verschoben, sondern gelöscht und neue erstellt. Dabei werden jedoch nur normale QStandardItems erzeugt und unsere Member aus den vererbten Klassen gehen verloren.

Aus diesem Grund haben wir diese Vorgehensweise über Bord geworfen, und anstatt verschiedener QStandardItem Klassen zu haben, speichern wir unsere Klassen nun einfach in einem QVariant in setData() des QStandardItems. Hoffe ihr könnt mir soweit folgen *g*

Das funktioniert soweit nun auch, jedoch gibt es nun beim starten einer Drag Aktion jede Menge Fehlermeldungen:

Bild

Weiß jemand woran das liegen könnte? ... Mit leerem data im QStandardItem tritt der Fehler nicht auf. Zuweisen tue ich es folgenderweise:

Code: Alles auswählen

void framework::addToScene(SceneObject* o, const QString& name) {
	QVariant object = qVariantFromValue<QObject*>(o);
	QStandardItem* item = new QStandardItem(name);
	item->setData(object);
   .....
}
Gruß nochmals und danke schonmal ;)[/code]
upsala
Beiträge: 3946
Registriert: 5. Februar 2006 20:52
Wohnort: Landshut
Kontaktdaten:

Beitrag von upsala »

Wahrscheinlich bringt euch das weiter. Im übrigen ist eine Fehlermeldung auch in Textform verständlich, man muß sie nicht grafisch darstellen...
buhrmi
Beiträge: 18
Registriert: 21. Oktober 2006 14:43
Kontaktdaten:

Beitrag von buhrmi »

DANKE! ;)

Verstehe ich das richtig, dass wenn wir nun mehrere verschiedene von QStandardItem abgeleitete Klassen in unserm TreeView haben, dass wir in dem moment wo das draggen gestartet wird (z.b. beim klicken), wir als Prototypen des Models das angeklickte Item setzen? Das würde dann bedeuten, dass jede Klasse eine eigene Clone methode bekommt, die für das neue Item alles wichtige aus dem ursprünglichen objekt kopiert. Is das richtig?

Gruß
upsala
Beiträge: 3946
Registriert: 5. Februar 2006 20:52
Wohnort: Landshut
Kontaktdaten:

Beitrag von upsala »

Keine Ahnung, aber Probiern geht über studiern...
buhrmi
Beiträge: 18
Registriert: 21. Oktober 2006 14:43
Kontaktdaten:

Beitrag von buhrmi »

da hascht du ohne jeden zweifel wohl rescht
buhrmi
Beiträge: 18
Registriert: 21. Oktober 2006 14:43
Kontaktdaten:

Beitrag von buhrmi »

Sodale,

nach viel probiern und auch studieren komm ich zu dem Schluss: Ich kriegs nicht hin! :cry:

Hier was ich habe und mein Ansatz:
  • Eine SceneObject Klasse, erbt von QStandardItem
    überlädt die QStandardItem::clone() methode mit dem Inhalt "return QStandardItem::clone()". Sie sollte also EXAKT dasselbe machen wie die basisklasse.
  • mehrere andere Klassen, die von SceneObject erben, mit genau derselben überladenen Funktion.
  • Eine ObjectsView Klasse, welche von QTreeView erbt.
    Bei dieser wurde der selectionChanged slot überladen, sodass er beim anklicken [pseudocode] model()->setItemPrototype(selectedItem) aufruft.
Das Programm quittiert immer mit einer unhandled Exception in qmap.h, sobald man ein Item von einer Position auf eine andere droppen lässt.

Noch ein Fehler ist, dass wenn ein Item selektiert wurde, und man danach ein anderes Item selektiert, verschwindet der Text des ursprüngliches Items einfach aus dem TreeView. Klickt man an die stelle, wo nun das leere Feld ist, gibt es ebenfalls eine unhandled Exception.

Bin total ratlos.

Ich finde auch keinen Beispielcode wo in einer QTreeView drag und drop verwendet wird mit QStandardItems... Hat jemand zufällig was an der Hand? Oder kann uns anders helfen?

Edit: Nach ein wenig weiterem Probiern hab ich festgestellt, dass der code gar nicht in die überladenen clone() methoden hineinspringt...
upsala
Beiträge: 3946
Registriert: 5. Februar 2006 20:52
Wohnort: Landshut
Kontaktdaten:

Beitrag von upsala »

Kann das Thema im Moment nicht testen. Aber schon mal darüber nachgedacht, nicht das QStandardItemModel zu verwenden sondern selbst eins aufzubauen, auf der Basis von QAbstractItemModel?
buhrmi
Beiträge: 18
Registriert: 21. Oktober 2006 14:43
Kontaktdaten:

Beitrag von buhrmi »

Hmm nein, wusste gar nicht das das geht. Werd mich da mal einlesen ;) Danke für deine Tipps upsala.

Aber: Falls jemand sich zufällig schonmal damit beschäftigt hat und weiß woran das liegt und was wir vielleicht falsch machen, vergessen haben könnten, etc dann nur rein damit. Auch Beispielcode ist gern gesehn.
Zandru
Beiträge: 84
Registriert: 29. Mai 2007 15:35

Beitrag von Zandru »

buhrmi hat geschrieben: [*]Eine SceneObject Klasse, erbt von QStandardItem
überlädt die QStandardItem::clone() methode mit dem Inhalt "return QStandardItem::clone()". Sie sollte also EXAKT dasselbe machen wie die basisklasse.
das klappt so nicht. dein clone() gibt einen Clone der Basisklasse zurück, also KEINE 1:1 Kopie.

aber wie upsala bereits meinte, QStandardItemModel ist nicht dazu gedacht, als Basisklasse verwendet zu werden.

Schau dir mal QAbstractItemModel an - theoretisch brauchst da nur die ganzen virtual Methoden implementieren und bist fertig.
Antworten