Drag and Drop QStandardItemModel in QML
Unsolved
QML and Qt Quick
-
Hi, i'm a newbie.
I want to drag and drop a item in Tree View in qml. I create item by QStandardItem::appendRow. But i don't understand how to drag and drop a item.
This is my code:
treeviewmodel.hclass TreeViewModel : public QStandardItemModel { Q_OBJECT public: explicit TreeViewModel(QObject *parent = nullptr); virtual ~TreeViewModel() = default; enum MyRoles { My_Role_ID = 1000, My_Role_Address, My_Role_Name, My_Role_Object, My_Role_Property, My_Role_Value }; Qt::DropActions supportedDropActions() const override; Qt::DropActions supportedDragActions() const override; virtual Qt::ItemFlags flags(const QModelIndex &index) const override; QStringList mimeTypes() const override; QMimeData * mimeData(const QModelIndexList &indexes) const override; bool dropMimeData(const QMimeData *data, Qt::DropAction action, int row, int column, const QModelIndex &parent) override; QHash<int, QByteArray> roleNames() const override; public slots: void newParent(QString name); private: QHash<int, QByteArray> m_roleNameMapping; };
treeviewmodel.c
#include "treeviewmodel.h" #include <QStandardItem> TreeViewModel::TreeViewModel(QObject *parent) : QStandardItemModel(parent) { m_roleNameMapping[My_Role_Name] = "name_role"; m_roleNameMapping[My_Role_Property] = "property_role"; m_roleNameMapping[My_Role_Value] = "value_role"; this->mimeTypes(); this->supportedDragActions(); this->supportedDropActions(); } Qt::DropActions TreeViewModel::supportedDropActions() const { return Qt::CopyAction | Qt::MoveAction; } Qt::DropActions TreeViewModel::supportedDragActions() const { return Qt::CopyAction | Qt::MoveAction; } Qt::ItemFlags TreeViewModel::flags(const QModelIndex &index) const { if (!index.isValid()){ return Qt::ItemIsDropEnabled | Qt::ItemIsDragEnabled; } return Qt::ItemIsDropEnabled | Qt::ItemIsDragEnabled | QAbstractItemModel::flags(index); } QStringList TreeViewModel::mimeTypes() const { QStringList types; types << "application/vnd.text.list"; return types; } QMimeData *TreeViewModel::mimeData(const QModelIndexList &indexes) const { QMimeData *mimeData = new QMimeData(); QByteArray encodedData; QDataStream stream(&encodedData, QIODevice::WriteOnly); foreach (const QModelIndex &index, indexes) { if (index.isValid()) { QString text = data(index, Qt::DisplayRole).toString(); stream << text; } } mimeData->setData("application/vnd.text.list", encodedData); return mimeData; } bool TreeViewModel::dropMimeData(const QMimeData *data, Qt::DropAction action, int row, int column, const QModelIndex &parent) { if(action == Qt::IgnoreAction){ return true; } if(!data->hasFormat("application/vnd.text.list")){ return false; } if(column >= columnCount(parent)){ return false; } int beginRow; if (row != -1){ beginRow = row; }else if(parent.isValid()){ beginRow = parent.row(); } else{ beginRow = rowCount(parent); } QByteArray encodedData = data->data("application/vnd.text.list"); QDataStream stream(&encodedData,QIODevice::ReadOnly); QStringList newItems; int rows = 0; while(!stream.atEnd()){ QString text; stream >> text; newItems << text; ++rows; } insertRows(beginRow, rows, parent); foreach (QString text, newItems) { QModelIndex idx = index(beginRow, 0, parent); setData(idx, text); beginRow++; } return true; } void TreeViewModel::newParent(QString name) { QStandardItem *parent = new QStandardItem(name); parent->setFlags(parent->flags() & ~Qt::ItemIsDragEnabled); parent->setData(name,My_Role_Name); this->appendRow(parent); } QHash<int, QByteArray> TreeViewModel::roleNames() const { return m_roleNameMapping; }
main.cpp
TreeViewModel *list_divice = new TreeViewModel; engine.rootContext()->setContextProperty("listdevice",list_divice);
qml file
C1.TreeView{ id: listLeftSide anchors.fill: parent model: listdevice selectionMode: SelectionMode.SingleSelection onDoubleClicked: { let currentDevice = listdevice.data(listLeftSide.currentIndex,1000) console.log(currentDevice) } C1.TableViewColumn{ role: "name_role" title: "Device" width: leftSide.width }
Sorry about my stupid question. I have sreached a lot but none of them not working. What's my wrong. Can someone give me a example. Thank you very much.
Sorry, my english's very bad