在Qt拖放中使用QMimeData传递数据

时间:2010-02-22 20:52:19

标签: c++ qt drag-and-drop mime-types

我试图了解在Qt中使用拖放时数据是如何传递的。根据我从我一直在研究的示例中所理解的,您首先通过覆盖通过QWidget继承的方法将窗口小部件定义为可拖动。

在重写方法的实现中,我一直在查看的示例实例化指向QMimeData对象的指针,并通过调用setText(const QString &text)setData(const QByteArray &data)将信息存储在其中。它们使用QByteArray运算符将信息存储在<<对象中:

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);

在接受drop的小部件中dropEvent()方法的定义中,使用>>运算符检索了这两个变量:

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

setData()方法中, application / x-fridgemagnet 作为MIME类型参数传递。那是在别的地方定义的还是它可以弥补的东西?

如何在QMimeData对象中存储和检索自定义对象?我试过这个:

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

并试图像这样检索它:

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

但是它不起作用,说“不匹配'运算符&gt;&gt;'”。关于我该怎么做的任何提示?

2 个答案:

答案 0 :(得分:6)

  

在setData()方法中,application / x-fridgemagnet作为MIME类型参数传递。那是在别的地方定义的还是它可以弥补的东西?

如果数据采用您自己的专有格式,那么您可以进行补充。但是,如果它是标准化的东西,比如图像,你可能想要使用已知的哑剧类型。

如果您已经支持序列化为XML,那么创建自己的mime类型,序列化为XML,然后在接收端反序列化将很容易。

  

如何在QMimeData对象中存储和检索自定义对象?

您需要创建非成员运算符(&lt;&lt;&lt;&gt;&gt;),以QDataStream支持的方式写出MyObject的成员数据。请参阅“阅读和编写其他Qt类”标题下的QDataStream documentation

这将涉及创建以下两种方法:

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

由于这些是非成员运算符,因此它们将在您的类外定义:

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>> */

答案 1 :(得分:3)

是的,您可以组成自己的MIME类型,以便在自己的应用程序中使用。显然,没有任何外部应用程序会知道它是什么,因此您将无法在自己的应用程序之外拖动。

关于存储您自己的对象,您需要定义流操作符,因为Qt对您的对象一无所知。 QDataStream仅为简单的内置类型定义流运算符。你需要定义像

这样的东西
QDataStream& operator<<( QDataStream& ds, const myClass& myObject )
{
    // Use existing QDataStream stream operators or other methods to serialise your object
    // ...
    // ...

    return ds;
}

同样,对于反序列化,您需要定义适当的operator>>