[Qt-interest] Drag and drop of specific data

Yuriy Rusinov yrusinov at gmail.com
Wed Sep 8 11:06:20 CEST 2010


Hello, Stephen !


>
> You also need to implement dropMimeData in the target model. Apart from that
> it should work (though I've never tried with QStandardItemModel), so you
> would need to post a small simple compilable example.

Source model is

file attrModel.h

class AttributesModel : public QStandardItemModel
{
public:
    AttributesModel (QObject *parent=0);
    AttributesModel (int rows, int cols, QObject *parent=0);
    virtual ~AttributesModel (void);

    Qt::ItemFlags flags (const QModelIndex &index) const;

    QMimeData *mimeData (const QModelIndexList &indexes) const;
    QStringList mimeTypes (void) const;
    Qt::DropActions supportedDropActions (void) const;

private:
    Q_OBJECT
};

file attrModel.cpp
#include <QMimeData>
#include <QDataStream>
#include <QByteArray>
#include <QtDebug>

#include "attrModel.h"

AttributesModel :: AttributesModel (QObject *parent)
    : QStandardItemModel (parent)
{
}

AttributesModel :: AttributesModel (int rows, int cols, QObject *parent)
    : QStandardItemModel (rows, cols, parent)
{
}

AttributesModel :: ~AttributesModel (void)
{
}

Qt::ItemFlags AttributesModel :: flags (const QModelIndex &index) const
{
    Qt::ItemFlags defaultFlags = QStandardItemModel::flags (index);

    if (index.isValid())
        return Qt::ItemIsDragEnabled  | Qt::ItemIsDropEnabled | defaultFlags;
    else
        return Qt::ItemIsDropEnabled | defaultFlags;
}

QMimeData * AttributesModel :: mimeData (const QModelIndexList &indexes) const
{
    QMimeData *mimeData = new QMimeData ();
    QByteArray encodedData;

    QDataStream stream (&encodedData, QIODevice::WriteOnly);
    for (int i=0; i<indexes.count(); i++)
    {
        QModelIndex ind = indexes[i];
        if (ind.isValid() && ind.column()==0)
        {
            int idAttr = ind.data (Qt::UserRole).toInt ();
            QString attrName = ind.data (Qt::DisplayRole).toString ();
            stream << idAttr;
            stream << attrName;
        }
    }

    qDebug () << __PRETTY_FUNCTION__ << encodedData.length();// <<
qBuffer.buffer();
    mimeData->setData("plain/text", encodedData);

    return mimeData;
}

QStringList AttributesModel :: mimeTypes (void) const
{
    QStringList types;
    types << "plain/text";
    return types;
}

Qt::DropActions AttributesModel :: supportedDropActions (void) const
{
    return Qt::CopyAction | Qt::MoveAction;
}

Target model is:
file catAttrsModel.h

class CatAttrsModel : public QStandardItemModel
{
public:
    CatAttrsModel (QObject *parent=0);
    CatAttrsModel (int rows, int cols, QObject *parent=0);
    virtual ~CatAttrsModel (void);

    Qt::ItemFlags flags (const QModelIndex &index) const;

    bool dropMimeData (const QMimeData *data, Qt::DropAction action,
                       int row, int column, const QModelIndex &parent);

    Qt::DropActions supportedDropActions() const;

private:
    Q_OBJECT
};

file catAttrsMode.cpp
#include <QMimeData>
#include <QtDebug>

#include "catAttrsModel.h"

CatAttrsModel :: CatAttrsModel (QObject *parent)
    : QStandardItemModel (parent)
{
}

CatAttrsModel :: CatAttrsModel (int rows, int cols, QObject *parent)
    : QStandardItemModel (rows, cols, parent)
{
}

CatAttrsModel :: ~CatAttrsModel (void)
{
}

Qt::ItemFlags CatAttrsModel :: flags (const QModelIndex &index) const
{
    Qt::ItemFlags defaultFlags = QStandardItemModel::flags(index);

    if (index.isValid())
        return Qt::ItemIsDragEnabled | Qt::ItemIsDropEnabled | defaultFlags;
    else
        return Qt::ItemIsDropEnabled | defaultFlags;
}

bool CatAttrsModel :: dropMimeData (const QMimeData *data,
Qt::DropAction action,
                                       int row, int column, const
QModelIndex &parent)
{
    qDebug () << __PRETTY_FUNCTION__ << data->formats () << row <<
column << action << parent;
    if (action == Qt::IgnoreAction)
        return true;

    if (!data->hasFormat("text/plain"))
        return false;

    int beginRow;

    if (row != -1)
        beginRow = row;
    else if (parent.isValid())
        beginRow = 0;
    else
        beginRow = rowCount (QModelIndex());

    QByteArray encodedData = data->data("text/plain");
    QDataStream stream (&encodedData, QIODevice::ReadOnly);
    QMap<int, QString> attrsData;
    while (!stream.atEnd())
    {
        int idAttr;
        QString attrName;
        stream >> idAttr >> attrName;
        attrsData.insert (idAttr, attrName);
    }

    int rows = attrsData.count ();
    insertRows (beginRow, rows, parent);
    QMap<int, QString>::const_iterator p=attrsData.constBegin();
    for (int i=beginRow; i<beginRow+rows && p!=attrsData.constEnd(); i++)
    {
        QModelIndex wInd = this->index (i, 0);
        setData (wInd, p.value(), Qt::DisplayRole);
        setData (wInd, p.key(), Qt::UserRole);
        p++;
    }

    return true;
}

Qt::DropActions CatAttrsModel :: supportedDropActions() const
{
    return Qt::CopyAction | Qt::MoveAction;
}


-- 
Best regards,
Sincerely yours,
Yuriy Rusinov.



More information about the Qt-interest-old mailing list