Qt拖放Treeview:我错过了什么

时间:2013-09-11 10:26:08

标签: c++ qt drag-and-drop treeview

我有一个标准的树视图,它正在查看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获取数据。 非常感谢您的帮助!

1 个答案:

答案 0 :(得分:2)

我找到了自己问题的答案。

数据被Qt插入模型中的所需位置“移动”,然后将其删除

这意味着有必要实现dropMimeData使用的clone()成员(必须尽可能重新实现)

这意味着窗口小部件必须作为指针存储在对象中,以便在树中轻松移动(否则必须在窗口小部件之间手动复制数据,因为没有QObject的默认副本(按设计)