1

我有一个标准的树视图,它正在查看 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 的 drop 实现 dropMimeData 或类似的特殊功能?因为我只是在移动,所以我希望对象指针完好无损。如果我确实需要实现 dropMimeData,拖动数据的 mimetype 是什么?我知道我可以使用模型选择看到它,但从逻辑上讲,我应该能够从 mimedata 中获取数据。非常感谢您的帮助!

4

1 回答 1

2

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

通过 Qt 将数据“移动”到模型中所需的位置,然后将其删除

这意味着有必要实现一个由 dropMimeData 使用的 clone() 成员(据我所知,它也必须重新实现)

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

于 2013-09-11T16:20:14.490 回答