[Qt-interest] How to get access to dropped element
Christof Warlich
christof at warlich.name
Fri Jan 1 23:26:19 CET 2010
I got it solved by myself. Just for reference to anyone else who may
come across the
same issue: The info w.r.t. the dropped data is available in
QAbstractItemModel::dropMimeData.
While this may not be so much a surprise, the QT documentation lacks a
description
of the default MIME-type being used
("application/x-qabstractitemmodeldatalist").
The following reimplementation of that function shows how get hold of
the contained data:
bool dropMimeData(const QMimeData *data, Qt::DropAction action, int
row, int column, const QModelIndex &parent) {
qDebug() << "TreeModel drop" << data->formats();
QByteArray itemData =
data->data("application/x-qabstractitemmodeldatalist");
QDataStream stream(&itemData, QIODevice::ReadOnly);
int r, c;
QMap<int, QVariant> v;
stream >> r >> c >> v;
qDebug() << "Row and column:" << r << " " << c;
for(QMap<int, QVariant>::iterator it = v.begin(); it != v.end();
it++) {
qDebug() << "Name:" << "," << it.value();
}
return QAbstractItemModel::dropMimeData(data, action, row,
column, parent);
}
Christof Warlich schrieb:
> Hi,
>
> it seems I'm really stuck after reading the manual over and over again:
>
> The (compilable) example below shall allow to drag items from a
> read-only list view to a read-write tree view. So far, insertion of
> items into the tree through drag and drop works fine, but I'm only able
> to insert default elements whenever a drop occurs, as I do not know how
> to find out which of the elements from the list were dropped.
>
> The insertion into my custon TreeItem data structure is done in
> insertRows() below. Is this the right way to do it? I do not see a way
> to get any information w.r.t. the dropped item there, so I guess it
> should be done somewhere else?
>
> Many thanks for any help,
>
> Christof
>
> #include <QtGui>
> #include <deque>
> // Readonly list data to choose from:
> const char *List[] = {"Willi", "Max", "Bert"};
> // The related read-only model:
> class ListModel: public QAbstractListModel {
> public:
> int rowCount(const QModelIndex &) const {
> return sizeof(List)/sizeof(List[0]);
> }
> QVariant data(const QModelIndex &index, int role) const {
> if (!index.isValid()) return QVariant();
> if(role == Qt::DisplayRole) return QVariant(List[index.row()]);
> else return QVariant();
> }
> Qt::ItemFlags flags(const QModelIndex &) const {
> return (Qt::ItemIsEnabled | Qt::ItemIsSelectable |
> Qt::ItemIsDragEnabled);
> }
> };
>
> // The destination tree data structure:
> struct TreeItem {
> TreeItem(const char *name, TreeItem *parent = 0):
> Name(name), Parent(parent) {}
> std::deque<TreeItem *> Children;
> int row() const {
> if(Parent) {
> std::deque<TreeItem *> &children = Parent->Children;
> for(size_t i = 0; i < children.size(); i++) {
> if(this == children[i]) return i;
> }
> }
> return 0;
> }
> const char *Name;
> TreeItem *Parent;
> } Root("Tree"); // The tree's root item;
> // The related read / write model:
> class TreeModel: public QAbstractItemModel {
> public:
> TreeModel(QObject *parent = 0): QAbstractItemModel(parent) {}
> int rowCount(const QModelIndex &parent) const {
> TreeItem *parentItem;
> if (!parent.isValid()) parentItem = &Root;
> else parentItem = static_cast<TreeItem *>
> (parent.internalPointer());
> return parentItem->Children.size();
> }
> int columnCount(const QModelIndex &) const {return 1;}
> QModelIndex index(int row, int column,
> const QModelIndex &parent) const {
> if (!hasIndex(row, column, parent)) return QModelIndex();
> TreeItem *parentItem;
> if (!parent.isValid()) parentItem = &Root;
> else parentItem = static_cast<TreeItem *>
> (parent.internalPointer());
> TreeItem *childItem = parentItem->Children[row];
> if (childItem) return createIndex(row, column, childItem);
> else return QModelIndex();
> }
> QModelIndex parent(const QModelIndex &child) const {
> if (!child.isValid()) return QModelIndex();
> TreeItem *childItem = static_cast<TreeItem *>
> (child.internalPointer());
> TreeItem *parentItem = childItem->Parent;
> if (parentItem == &Root) return QModelIndex();
> return createIndex(parentItem->row(), 0, parentItem);
> }
> QVariant data(const QModelIndex &index, int role) const {
> if (!index.isValid()) return QVariant();
> TreeItem *treeItem = static_cast<TreeItem *>
> (index.internalPointer());
> if (role == Qt::DisplayRole) return QVariant(treeItem->Name);
> else return QVariant();
> }
> QVariant headerData(int, Qt::Orientation orientation,
> int role) const {
> if (orientation == Qt::Horizontal && role == Qt::DisplayRole)
> return QVariant(Root.Name);
> else return QVariant();
> }
> Qt::ItemFlags flags(const QModelIndex &) const {
> return Qt::ItemIsDropEnabled | Qt::ItemIsEnabled |
> Qt::ItemIsSelectable;
> }
> bool insertRows(int position, int rows,
> const QModelIndex &parent = QModelIndex()) {
> beginInsertRows(parent, position, position + rows - 1);
> TreeItem *parentItem;
> if (!parent.isValid()) parentItem = &Root;
> else parentItem = static_cast<TreeItem *>
> (parent.internalPointer());
> std::deque<TreeItem *> &list = parentItem->Children;
> for (int row = 0; row < rows; ++row) {
> // How could I get the dragged item's name here?
> list.insert(list.begin() + position,
> new TreeItem("DraggedName", parentItem));
> }
> endInsertRows();
> return true;
> }
> // This one never gets called. How can I remove items from the tree?
> bool removeRows(int position, int rows, const QModelIndex &parent) {
> beginRemoveRows(parent, position, position + rows - 1);
> TreeItem *parentItem;
> if (!parent.isValid()) parentItem = &Root;
> else parentItem = static_cast<TreeItem *>
> (parent.internalPointer());
> std::deque<TreeItem *> &list = parentItem->Children;
> for (int row = 0; row < rows; ++row) {
> std::deque<TreeItem *>::iterator
> it = list.begin() + position;
> list.erase(it);
> delete *it;
> }
> endRemoveRows();
> return true;
> }
> };
>
> // Putting it all together:
> int main(int argc, char *argv[]) {
> QApplication app(argc, argv);
> QSplitter *splitter = new QSplitter;
>
> ListModel *listModel = new ListModel;
> QListView *listView = new QListView(splitter);
> listView->setDragEnabled(true);
> listView->setModel(listModel);
>
> TreeModel *treeModel = new TreeModel;
> QTreeView *treeView = new QTreeView(splitter);
> treeView->setAcceptDrops(true);
> treeView->setModel(treeModel);
>
> splitter->setWindowTitle("Drag items from list to tree.");
> splitter->show();
> return app.exec();
> }
> _______________________________________________
> Qt-interest mailing list
> Qt-interest at trolltech.com
> http://lists.trolltech.com/mailman/listinfo/qt-interest
>
More information about the Qt-interest-old
mailing list