Seite 1 von 1
Kleine Hilfestellung für uns bei Drag&Drop in einem Tree
Verfasst: 27. Mai 2007 13:11
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
Verfasst: 27. Mai 2007 13:59
von upsala
Das schon mal durchgelesen?
Drag and Drop
Verfasst: 31. Mai 2007 13:25
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:
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]
Verfasst: 31. Mai 2007 19:30
von upsala
Wahrscheinlich bringt euch
das weiter. Im übrigen ist eine Fehlermeldung auch in Textform verständlich, man muß sie nicht grafisch darstellen...
Verfasst: 1. Juni 2007 20:24
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ß
Verfasst: 1. Juni 2007 20:34
von upsala
Keine Ahnung, aber Probiern geht über studiern...
Verfasst: 2. Juni 2007 01:16
von buhrmi
da hascht du ohne jeden zweifel wohl rescht
Verfasst: 4. Juni 2007 11:16
von buhrmi
Sodale,
nach viel probiern und auch studieren komm ich zu dem Schluss: Ich kriegs nicht hin!
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...
Verfasst: 4. Juni 2007 12:21
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?
Verfasst: 4. Juni 2007 13:59
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.
Verfasst: 4. Juni 2007 18:04
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.