[gelöst] Drag'n'Drop von List-Model/View zu QTextEidt (MIME
Verfasst: 7. August 2011 16:50
Hallo,
Ausgangslage und Zielsetzung
Ich habe ein Model/View, welches mir eine Liste an Strings anzeigt. Das Model ist abgeleitet von QAbstractListModel und beim View handelt es sich um QListView. Von diesem Model/View möchte ich eine Zeile per Drag'n'Drop in ein abgeleitetes QTextEdit Feld kopieren.
Das Problem
Beim Loslassen über dem QTextEdit-Feld wird nicht der gewünschte Text sondern irgendwelche Sonderzeichen kopiert.
Fehlersuche
Ich habe mich solange an der Doku http://doc.qt.nokia.com/4.4/model-view-dnd.html orientiert bis es zum Thema der MIME-Data kam. Hier habe ich leider mehr blind Quellcode abgeschrieben, anstatt diesen wirklich zu verstehen. Jedoch gibt es zum Stichwort MIME in diesem Forum eigentlich keine Beiträge und auch hilft mir ausnahmsweise weder Google noch die Qt Doku richtig weiter. Somit nun hier meine Verständnisfragen.
Verständnisfragen
In der Doku wird für den Export aus dem Model/View ein eigener MIME-Type "application/vnd.text.list" definiert:
und erzeugt den encoded Inhalt durch:
Erste Frage: Warum ein eigener MIME-Type? Könnte man denn nicht einfach mit "plain/text" arbeiten. Man will ja schließlich nur den Text vom Item und könnte sich somit doch später beim Drop ein separat zu implementierendes Decoding ersparen.
Zweite Frage (hoffentlich ist diese Frage nicht allzu bescheuert): Wer ruft die Funktion "*DragDropListModel::mimeData" eigentlich auf, denn wohin übergibt denn "return mimeData;" den encoded Inhalt?
Irgendwie klar, wenn man was encoded, dann muss man es später auch decoden. Das Beispiel in der Doku gibt hierfür folgendes Beispiel
Dritte Frage: Da ich leider nicht verstanden habe, wie man nun außerhalb der Klasse DragDropListModel auf den encoded Inhalt zugreifen kann (siehe zweite Frage), ist mir nun auch unklar, wo im Beispiel die Klasse data herkommt (QByteArray encodedData = data->data("application/vnd.text.list");
Ich habe das Ganze, so wie ich dachte das es eigentlich auch klappen müsste als kompilierbare Minimalversion in Form einer zip-Datei angehängt. Kurzbeschreibung zur Anlage:
Es gibt zwei Klassen. Eine für das Model mit den QStringList Daten. Aus dieser Klasse sollen Textzeile per Drag'n'Drop heraus kopiert werden:
Der Export/encoding:
Sowie ein Klasse abgeleitet von QTextEdit, in dem der Drop statt finden soll:
Bei dem eigentlich ein Decoding fehlt (siehe meine Verständnisfragen). D.h. beim Drop-Event müsste doch was geändert werden (doch was???):
Entschuldigt die Länge dieses Beitrages. Aber ich hoffe, dass durch diese etwas ausführliche Beschreibung spätere Leser das Problem und durch die hoffentlich folgenden klärenden Kommentare besser ein Drag'n'Drop mit Export/Import bzw. En- und Decoding nachvollziehen können. Ist ja auch anscheinend einer der ersten Beiträge zu diesem Thema.
Ausgangslage und Zielsetzung
Ich habe ein Model/View, welches mir eine Liste an Strings anzeigt. Das Model ist abgeleitet von QAbstractListModel und beim View handelt es sich um QListView. Von diesem Model/View möchte ich eine Zeile per Drag'n'Drop in ein abgeleitetes QTextEdit Feld kopieren.
Das Problem
Beim Loslassen über dem QTextEdit-Feld wird nicht der gewünschte Text sondern irgendwelche Sonderzeichen kopiert.
Fehlersuche
Ich habe mich solange an der Doku http://doc.qt.nokia.com/4.4/model-view-dnd.html orientiert bis es zum Thema der MIME-Data kam. Hier habe ich leider mehr blind Quellcode abgeschrieben, anstatt diesen wirklich zu verstehen. Jedoch gibt es zum Stichwort MIME in diesem Forum eigentlich keine Beiträge und auch hilft mir ausnahmsweise weder Google noch die Qt Doku richtig weiter. Somit nun hier meine Verständnisfragen.
Verständnisfragen
In der Doku wird für den Export aus dem Model/View ein eigener MIME-Type "application/vnd.text.list" definiert:
Code: Alles auswählen
QStringList DragDropListModel::mimeTypes() const
{
QStringList types;
types << "application/vnd.text.list";
return types;
}Code: Alles auswählen
QMimeData *DragDropListModel::mimeData(const QModelIndexList &indexes) const
{
QMimeData *mimeData = new QMimeData();
QByteArray encodedData;
QDataStream stream(&encodedData, QIODevice::WriteOnly);
foreach (QModelIndex index, indexes) {
if (index.isValid()) {
QString text = data(index, Qt::DisplayRole).toString();
stream << text;
}
}
mimeData->setData("application/vnd.text.list", encodedData);
return mimeData;
}Zweite Frage (hoffentlich ist diese Frage nicht allzu bescheuert): Wer ruft die Funktion "*DragDropListModel::mimeData" eigentlich auf, denn wohin übergibt denn "return mimeData;" den encoded Inhalt?
Irgendwie klar, wenn man was encoded, dann muss man es später auch decoden. Das Beispiel in der Doku gibt hierfür folgendes Beispiel
Code: Alles auswählen
QByteArray encodedData = data->data("application/vnd.text.list");
QDataStream stream(&encodedData, QIODevice::ReadOnly);
....Ich habe das Ganze, so wie ich dachte das es eigentlich auch klappen müsste als kompilierbare Minimalversion in Form einer zip-Datei angehängt. Kurzbeschreibung zur Anlage:
Es gibt zwei Klassen. Eine für das Model mit den QStringList Daten. Aus dieser Klasse sollen Textzeile per Drag'n'Drop heraus kopiert werden:
Code: Alles auswählen
class subclassed_Model : public QAbstractListModel {
Q_OBJECT
public:
subclassed_Model(const QStringList &strings, QObject *parent = 0);
// Item data handling
int rowCount ( const QModelIndex & parent = QModelIndex() ) const;
QVariant data( const QModelIndex & index, int role ) const;
// Drag-n-Drop support and MIME data handling
Qt::DropActions supportedDragActions() const;
Qt::ItemFlags flags(const QModelIndex &index) const;
QMimeData *mimeData(const QModelIndexList &indexes) const;
private:
QStringList stringListe;
};Code: Alles auswählen
QMimeData *subclassed_Model::mimeData(const QModelIndexList &indexes) const
{
QMimeData *mimeData = new QMimeData();
QByteArray encodedData;
QDataStream stream(&encodedData, QIODevice::WriteOnly);
foreach (QModelIndex index, indexes) {
if (index.isValid()) {
QString text = data(index, Qt::DisplayRole).toString();
stream << text;
}
}
mimeData->setData("text/plain", encodedData);
return mimeData;
}Code: Alles auswählen
class subclassed_QTextEdit : public QTextEdit {
Q_OBJECT
public:
subclassed_QTextEdit(QWidget *parent=0);
protected:
void dragEnterEvent(QDragEnterEvent *event);
void dragMoveEvent(QDragMoveEvent *event);
void dropEvent(QDropEvent *event);
};Code: Alles auswählen
void subclassed_QTextEdit::dropEvent(QDropEvent *event) {
const QMimeData *mimeData = event->mimeData();
append(mimeData->text());
event->setDropAction(Qt::CopyAction);
event->accept();
}