我想要做的与this非常相似。除了我正在使用具有树结构并且不仅仅对行和列感兴趣的QAbstractItemModel。事实上,在我的模型中,列始终为0.但是为了实现拖放,我需要获取internalPointer()返回的父项,子项和不透明指针。这是一些相关的代码。 CTreeView扩展了QTreeView。
void CTreeView::dragEnterEvent(QDragEnterEvent* event)
{
if (event->mimeData()->hasFormat("application/x-qabstractitemmodeldatalist"))
{
event->acceptProposedAction();
}
}
void CTreeView::dropEvent(QDropEvent* event)
{
const QMimeData* mime_data = event->mimeData();
QByteArray encoded_data =
mime_data->data("application/x-qabstractitemmodeldatalist");
QDataStream stream(&encoded_data, QIODevice::ReadOnly);
while (!stream.atEnd())
{
// I can do this.
int row, column;
stream >> row >> column;
// But how do I construct the QModelIndex to get the parent, children,
// and opaque pointer?
// I have seen other advice that mentions doing this.
QMap<int, QVariant> role_data_map;
stream >> row >> col >> role_data_map;
// Which allows you to do this.
QList<int> keys = role_data_map.keys();
BOOST_FOREACH(int key, keys)
{
QVariant variant = role_data_map[key];
// use the variant
}
// But that only gets me part of the way there.
}
}
有什么想法吗?我只想在树视图中支持拖放,所以我正在考虑将selectedIndexes()的QModelIndexList存储在我的子类的成员变量中,并直接在dropEvent()中对其进行操作。这似乎在某种程度上作弊,所以我仍然对Qt方式感兴趣。请让我知道你对这个想法的看法。
答案 0 :(得分:0)
首先,从您的代码看起来,您正在以错误的方式执行:您不应在视图中重载dropEvent,而应在模型中使用dropMimeData。以下文档解释了如何使用Qt的模型/视图框架进行dnd:
http://doc.trolltech.com/latest/model-view-dnd.html
至于您的具体问题,即访问已删除项目的internalPointer()。将索引存储在类的索引中是危险且容易出错的。您要做的是将您需要的信息存储在mime数据中。我不知道你的用例是什么,所以我无法猜出这个有用的数据是什么 - 但如果你只需要internalPointer的值(并且可以确保在收到drop事件时该值仍然有效),你可以只需存储它,就像你决定格式一样。例如,如果您的数据在某处被唯一ID引用(如数据库中的行ID),则可以存储此信息并在模型中使用自定义索引(int rowid)方法从该信息构造QModelIndex。通常,索引的internalPointer在创建期间设置,因此这将允许获取所有需要的信息。
如果您告诉我们您如何创建索引,我们可以提供更多帮助。