拖放,拖动和释放(Drag and Drop),允许用户利用鼠标在不同组件之间或一个组件上进行数据的拖动。如果哪个组件支持拖放操作,就在该组件的设计上实现某些必要的函数。比如说,我们可能需要在MainWindow这个主窗口上实现拖放,那就在这个类中实现一些函数。如果我们自定义了一个组件,比如说定义了一个类MyDnDWidget继承自QWidget,我们就在MyDndWidget类中实现特定的函数来支持拖放。
Drag and Drop Types
QMimeData类是Qt内部的一个容器,它记录着大量拥有Mime Type(元类型)的数据。可以把它当成是一个map,每一个元素都是”Mime Type, Mime Data”这样的键值对,但是使用的时候不要像map一样使用,只是用于理解。
拖放操作不只局限在文本和图像上,任何类型的信息在拖放操作中都能被转换。为了在应用之间拖动信息,这些应用彼此都应该知道他们允许接收哪种数据格式,同时也应该知道他们可以产生哪种数据格式。这个是由MIME Types实现的。
被构造的QDrag对象包含MIME Types的列表,它能使用这些去表现数据,同时接收拖动数据的那个窗体使用这些MIME Types中的一个去访问数据。Mime Type可以是Qt中提供的,也可以是用户自定义的,如果需要自定义一个Mime Type,可以重新实现mimeTypes()函数:
mimeTypes
QStringList QAbstractItemModel::mimeTypes() const
这个函数返回允许的Mime Types列表。默认情况下,内置的models和views使用内部的Mime Type,比如text/uri-list。
当重新实现一个支持拖放操作的model时,如果设计者想要返回的数据格式不同于内部的Mime Type,那就需要重新实现这个函数来返回自定义的Mime Types列表。通常的实现形式为:
QStringList types;
types << /* the custom mime types */;
return types;
如果在自定义model中重新实现了这个函数,那么同时也需要重新实现mimeData()和dropMimeData()函数:
mimeData
QMimeData *QAbstractItemModel::mimeData(const QModelIndexList &indexes) const
这个函数返回一个QMimeData *类型的对象,这个对象包含序列化的数据元素,而那些数据元素存储在形参indexes中。换句话说,就是将模型索引列表indexes中的数据序列化,然后存储在一个QMimeData中,最后返回这个QMimeData指针。序列化的方法是使用QByteArray和QDataStream两个类。通常的实现格式为:
if(indexes.isEmpty())
return