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 のドロップのために、dropMimeData または同様に特別なものを実装する必要がありますか? 私は移動しているだけなので、オブジェクト ポインタがそのままであることを期待していました。dropMimeData を実装する必要がある場合、ドラッグされたデータの MIME タイプは何ですか? モデル選択を使用して表示できることはわかっていますが、論理的には mimedata からデータを取得できるはずです。あなたの助けに感謝します!

4

1 に答える 1

2

さて、私は自分の質問に対する答えを見つけました。

データは、Qt がモデル内の必要な位置に挿入してから削除することによって「移動」されます。

これは、dropMimeData で使用される clone() メンバーを実装する必要があることを意味します (これも再実装する必要があります)。

これは、ツリー内で簡単に移動できるように、オブジェクト内にポインターとしてウィジェットを格納する必要があることを意味します (それ以外の場合は、QObjects のデフォルトのコピーがないため (設計上)、ウィジェット間でデータを手動でコピーする必要があります)。

于 2013-09-11T16:20:14.490 に答える