How to Drag and Drop working with tableview?
I have tried to implement moving rows with by drag and drop in tableview with my custom model. I have read everything I have found regarding this, and I just don't get it to work with tableview. It's working perfectly with listview.
In tableview row is copied correctly, but removerows is not called. What I am missing? If I have to call removerows directly where should I do it. I would like to be able to use the same model with listview and tableview. I feel that I am missing something trivial, but I just don't get what.
Here is simplified example:
Code:
#include <QtGui>
#include "stringlistmodel.h"
#include <QAbstractItemModel>
int main(int argc, char *argv[])
{
numbers << "One" << "Two" << "Three" << "Four" << "Five";
tableView->setDragEnabled(true);
tableView->setAcceptDrops(true);
tableView->setDropIndicatorShown(true);
tableView->setModel(model);
tableView->setDefaultDropAction(Qt::MoveAction);
tableView->show();
listView->setDragEnabled(true);
listView->setAcceptDrops(true);
listView->setModel(model);
listView->setDefaultDropAction(Qt::MoveAction);
listView->show();
return app.exec();
}
This is my model header:
Code:
#ifndef STRINGLISTMODEL_H
#define STRINGLISTMODEL_H
#include <QAbstractListModel>
#include <QStringList>
#include <QMimeData>
{
Q_OBJECT
public:
QVariant headerData
(int section, Qt
::Orientation orientation,
int role = Qt::DisplayRole) const;
int role = Qt::EditRole);
Qt::DropActions supportedDropActions() const;
QMimeData *mimeData
(const QModelIndexList
&indexes
) const;
bool dropMimeData
(const QMimeData *data, Qt
::DropAction action,
int row,
int column,
const QModelIndex &parent
);
private:
signals:
public slots:
};
#endif // STRINGLISTMODEL_H
and this is my model source:
Code:
#include "stringlistmodel.h"
#include <QStringListModel>
#include <QDebug>
{
}
int StringListModel
::rowCount(const QModelIndex &parent
) const {
return stringList.count();
}
{
if (!index.isValid())
if (index.row() >= stringList.size())
if (role == Qt::DisplayRole || role == Qt::EditRole)
return stringList.at(index.row());
else
}
QVariant StringListModel
::headerData(int section, Qt
::Orientation orientation,
int role) const
{
if (role != Qt::DisplayRole)
if (orientation == Qt::Horizontal)
return QString("Column %1").
arg(section
);
else
return QString("Row %1").
arg(section
);
}
Qt
::ItemFlags StringListModel
::flags(const QModelIndex &index
) const {
if (index.isValid())
return Qt::ItemIsDragEnabled | Qt::ItemIsDropEnabled | defaultFlags;
else
return Qt::ItemIsDropEnabled | defaultFlags;
}
bool StringListModel
::setData(const QModelIndex &index,
{
if (index.isValid() && role == Qt::EditRole) {
stringList.replace(index.row(), value.toString());
emit dataChanged(index, index);
return true;
}
return false;
}
bool StringListModel
::insertRows(int position,
int rows,
const QModelIndex &parent
) {
beginInsertRows
(QModelIndex(), position, position
+rows
-1);
for (int row = 0; row < rows; ++row) {
stringList.insert(position, "");
}
endInsertRows();
return true;
}
bool StringListModel
::removeRows(int position,
int rows,
const QModelIndex &parent
) {
beginRemoveRows
(QModelIndex(), position, position
+rows
-1);
for (int row = 0; row < rows; ++row) {
stringList.removeAt(position);
}
endRemoveRows();
return true;
}
Qt::DropActions StringListModel::supportedDropActions() const
{
return Qt::CopyAction | Qt::MoveAction;
}
{
types << "application/vnd.text.list";
return types;
}
QMimeData *StringListModel
::mimeData(const QModelIndexList
&indexes
) const {
if (index.isValid()) {
QString text
= data
(index, Qt
::DisplayRole).
toString();
stream << text;
}
}
mimeData->setData("application/vnd.text.list", encodedData);
return mimeData;
}
bool StringListModel
::dropMimeData(const QMimeData *data,
Qt
::DropAction action,
int row,
int column,
const QModelIndex &parent
){
qDebug() << action;
if (action == Qt::IgnoreAction)
return true;
if (!data->hasFormat("application/vnd.text.list"))
return false;
if (column > 0)
return false;
int beginRow;
if (row != -1)
beginRow = row;
else if (parent.isValid())
beginRow = parent.row();
else
QByteArray encodedData
= data
->data
("application/vnd.text.list");
int rows = 0;
while (!stream.atEnd()) {
stream >> text;
newItems << text;
++rows;
}
foreach
(const QString &text, newItems
) { setData(idx, text);
beginRow++;
}
return true;
}
Re: How to Drag and Drop working with tableview?
Try setting the dragDropOverWriteMode property to false on your table view. link
Re: How to Drag and Drop working with tableview?
Thanks a lot! That was the solution.