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 からデータを取得できるはずです。あなたの助けに感謝します!