Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Passing data around with QMimeData in Qt drag and drop

I'm trying to understand how data gets passed around when using drag and drop in Qt. From what I understood from the examples I've been studying, you first define a widget as draggable by overriding methods inherited through QWidget.

In the implementation of the overridden method, the examples I've been looking at instantiate a pointer to a QMimeData object, and store information in it by calling setText(const QString &text) and setData(const QByteArray &data). They store information in the QByteArray object with the << operator:

QByteArray itemData;
QDataStream dataStream(&itemData, QIODevice::WriteOnly);

dataStream << labelText << QPoint(ev->pos() - rect().topLeft());

QMimeData *mimeData = new QMimeData;
mimeData->setData("application/x-fridgemagnet", itemData);
mimeData->setText(labelText);

In the definition of the dropEvent() method in the widget that accepts the drops, both of those variables were retrieved with the >> operator:

QString text;
QPoint offset;
dataStream >> text >> offset;

In the setData() method, application/x-fridgemagnet was passed as a MIME type argument. Was that defined somewhere else or its just something you can make up?

How can I store and retrieve a custom object inside the QMimeData object? I tried this:

dataStream << labelText << QPoint(ev->pos() - rect().topLeft()) << myObject;

and tried to retrieve it like this:

myClass myObject;
dataStream >> text >> offset >> myObject;

But it didn't work, says theres "no match for 'operator >>'". Any tips on what should I do?

like image 257
liewl Avatar asked Feb 22 '10 20:02

liewl


1 Answers

In the setData() method, application/x-fridgemagnet was passed as a MIME type argument. Was that defined somewhere else or its just something you can make up?

If the data is in your own proprietary format, then you can make it up. If, however, it's something standardized, like images, you'll probably want to use a known mime-type.

If you already support serialization to XML, then it would be easy to create your own mime-type, serialize to XML, and then de-serialize on the receiving end.

How can I store and retrieve a custom object inside the QMimeData object?

You'll need to create non-member operators (<< and >>) that write out MyObject's member data in a way supported by QDataStream. See the QDataStream documentation under the heading "Reading and Writing other Qt Class."

That will involve creating the following two methods:

QDataStream &operator<<(QDataStream &, const MyObject &);
QDataStream &operator>>(QDataStream &, MyObject &);

Since these are non-member operators, they will be defined outside your class:

class MyObject { /* ... */ };

QDataStream &operator<<(QDataStream &stream, const MyObject &obj) {
    /* as long as first_member and second_member are types supported
       by QDataStream, I can serialize them directly.  If they're not
       supported, I'd need an operator for them as well unless I can
       convert them to a QString or something else supported by Qt /
       QDataStream */
    stream << obj.first_member;
    stream << obj.second_member;
    /* and so on and so forth */
    return stream;
}
/* and similarly for operator>> */
like image 191
Kaleb Pederson Avatar answered Oct 05 '22 18:10

Kaleb Pederson