我有一个标准的树视图,它正在查看QStandardItemModel的子类。
模型中的项目也是QStandardItem的子类。这些项目有一个额外的对象指针,我用它来存储指向我的数据类实例的指针,一个“阶段”(本身就是一个QObject)。所有项目都有指向它的阶段或子类的指针,或者_object中的NULL指针。
class MyStandardItem : public QStandardItem
{
public:
MyStandardItem();
MyStandardItem(const QString &text);
MyStandardItem(const QIcon &icon, const QString &text);
~MyStandardItem();
void object(QObject *object) {_object = object;}
QObject *object(){return _object;}
private:
QObject *_object;
};
我想在树视图中移动项目,但有一些限制。我已经给出了树视图的正确政策:
view->setAcceptDrops(true);
view->setDragEnabled(true);
view->setDropIndicatorShown(true);
view->setDragDropMode(QAbstractItemView::InternalMove);
在我的模型中,我提供以下内容:
Qt::DropActions MyStandardItemModel::supportedDropActions() const
{
return Qt::MoveAction;
}
Qt::ItemFlags MyStandardItemModel::flags(const QModelIndex &index) const
{
Qt::ItemFlags defaultFlags = Qt::ItemIsEnabled | Qt::ItemIsSelectable;
MyStandardItem *item = dynamic_cast<MyStandardItem*>(itemFromIndex(index));
if(!item || !item->object())
{
return defaultFlags;
}
Stage *stage = dynamic_cast<Stage*>(item->object());
switch (stage->type())
{
case Stage::STAGEA:
return Qt::ItemIsDropEnabled | defaultFlags;
break;
case Stage::STAGEB:
case Stage::STAGEC:
return Qt::ItemIsDragEnabled | defaultFlags;
break;
}
return defaultFlags;
}
拖动行为看起来不错。但是当我单击树视图中的拖动项目时,所选项目的对象指针是垃圾:
void Project::model_clicked(const QModelIndex& index)
{
MyStandardItem *item = static_cast<MyStandardItem*>(_tree_model->itemFromIndex(index));
if(!item || !item->isValid())
return;
QObject *object = item->object();
if(!object)
return;
// object is junk
Stage *stage = static_cast<Stage*>(object);
// and of course stage is junk
}
我是否需要为我的子类MyStandardItem实现dropMimeData或类似特殊的东西?因为我只是移动我期望对象指针是完整的。 如果我确实需要实现dropMimeData,那么拖动数据的mimetype是什么?我知道我可以使用模型选择看到它,但从逻辑上讲,我应该能够从mimedata获取数据。 非常感谢您的帮助!
答案 0 :(得分:2)
我找到了自己问题的答案。
数据被Qt插入模型中的所需位置“移动”,然后将其删除。
这意味着有必要实现dropMimeData使用的clone()成员(必须尽可能重新实现)
这意味着窗口小部件必须作为指针存储在对象中,以便在树中轻松移动(否则必须在窗口小部件之间手动复制数据,因为没有QObject的默认副本(按设计)