QTableView mit QAbstractTableModel und Drag&Drop



  • Hallo,

    Ich bin etwas überfordert wie ich mit QTableView und QAbstractTableModel ein 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 QTableView und QAbstractTableModel ist 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 List QList<MeasurementData> beinhaltet.

    Ich schalte beim Sender QTableView sowie im QAbstractTableModel alle 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 der dropMimeData() Methode füge ich die serialisierten Daten wieder in die QList<MeasurementData>. Komisch finde ich aber, dass danach auf der Sender-Seite die setData()-Methode aufgerufen wird. Da die Zeile beim Sender nicht gelöscht wird, lösche ich sie in der setData()-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!!").

    1. Wie implementiere ich Drag&Drop richtig, damit Model und View beide zufrieden sind?
    2. 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.
    3. 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 Problem

    Tutorials auf doc.qt.io
    Model/View Tutorial
    Model/View Programming

    [1] The Book of Qt 4, Daniel Molkentin
    [2] Advanced Qt Programming, Mark Summerfield



    1. 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 Liste QList<MeasurementData> zuerst mit insertRows() eine Zeile hinzufügen und danach jede Zelle einzeln mit setData() abfüllen sollen.

    2. Nachdem dropMimeData() seinen Teil gemacht hat, habe ich das manuelle Löschen im setData() entfernt (im Code auskommentiert). Stattdessen habe ich auf QTableView::setDragDropOverwriteMode(false) gesetzt, was standartmässig auf true ist. Dann löscht die QTableView internt auf der Sender-Seite die Zeile mit QTableView::removeRows().

    3. 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/


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.