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?
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>> */
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With