QTableView mit QAbstractTableModel und Drag&Drop
-
Hallo,
Ich bin etwas überfordert wie ich mit
QTableViewundQAbstractTableModelein korrektes Drag&Drop einer ganzen Zeile implementieren soll. Ein unvollständiges Exemplar ist als YouTube Video im Abspann zu sehen.Leider hat es in den Examples kein 1:1 Beispiel dazu. Ein einfaches Beispiel mit
QTableViewundQAbstractTableModelist das "Address Book Example", aber ohne Drag&Drop. Das "Drag and Drop Puzzle Example" ist schon ganz anders und mit anderen Super-Klassen (QListWidget, QWidget).
Auch in den Büchern [1][2], die ich gerade lese, finde ich nichts, das GENAU so ein Beispiel hat, obwohl es ein ganz einfaches Beispiel wäre...Ich habe auf Sender und auf Empfänger-Seite je eine Instanz der gleichen Klasse
TableModel, die eine ListQList<MeasurementData>beinhaltet.Ich schalte beim Sender
QTableViewsowie imQAbstractTableModelalle Drag-Funktionen ein, auf View-Ebene wie auch auf Zell-Ebene im Model. Ich kann eine Zelle draggen und auch beim Empfänger droppen. In derdropMimeData()Methode füge ich die serialisierten Daten wieder in dieQList<MeasurementData>. Komisch finde ich aber, dass danach auf der Sender-Seite diesetData()-Methode aufgerufen wird. Da die Zeile beim Sender nicht gelöscht wird, lösche ich sie in dersetData()-Methode. In der darauffolgenden "data()"-Methode möchte nun die View plötzlich die Zeile anzeigen, die ich zuvor gelöscht habe (Debug Meldung"Should not happen!!").- Wie implementiere ich Drag&Drop richtig, damit Model und View beide zufrieden sind?
- Im Video-Exemplar auf YouTube kann ich zwar Zeilen verschieben, wenn ich sie unter die vorhandenen Zeilen droppe. Wie kann ich auch Zeilen verschieben, wenn ich sie auf bestehende Zeilen droppe? Ziel: neue Zeile erstellen, nicht ersetzen.
- Nur Kosmetisch: statt auf eine Zelle zu droppen wäre es schön zwischen zwei bestehenden Zeilen ein "Indikator" darzustellen. Ist das mit wenig Aufwand möglich?
GitHub Projekt: DragAndDrop
YouTube Video: QTableView ProblemTutorials auf
doc.qt.io
Model/View Tutorial
Model/View Programming[1] The Book of Qt 4, Daniel Molkentin
[2] Advanced Qt Programming, Mark Summerfield -
-
Ich konnte das Drag&Drop selber lösen. Zum einen hätte ich gewisse Signale gar nicht "emittieren" sollen. Zum anderen hätte ich statt im
dropMimeData()die Daten direkt in die ListeQList<MeasurementData>zuerst mitinsertRows()eine Zeile hinzufügen und danach jede Zelle einzeln mitsetData()abfüllen sollen. -
Nachdem
dropMimeData()seinen Teil gemacht hat, habe ich das manuelle Löschen imsetData()entfernt (im Code auskommentiert). Stattdessen habe ich aufQTableView::setDragDropOverwriteMode(false)gesetzt, was standartmässig auftrueist. Dann löscht dieQTableViewinternt auf der Sender-Seite die Zeile mitQTableView::removeRows(). -
Da habe ich noch keine Lösung gefunden. Ich vermute etwas mit
QTableView::setItemDelegate()wäre möglich...
Code ist upgedatet auf github.com/te-bachi/QtProjects/DragAndDrop/
-