Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

Drag and Drop QStandardItemModel in QML



  • 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.h

    class 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



  • Me too, This is my problem, Does anybody help us???



  • can someone help me, pls


Log in to reply