3

QTreeViewから継承したカスタムモデルがあります。ドラッグアンドドロップを有効にしましたが、現在、アイテムをツリーにドロップできます。ただし、現在、既存のアイテムまたはアイテム間でドロップできます。これを制限して、既存のアイテムにのみドロップできるようにします。

DragDropOverwriteModeをtrueに設定しました(実際には、これがQTreeViewのデフォルトです)。ただし、これはアイテム間をドロップすることを妨げるものではありません。つまり、既存のアイテムにドロップすることもできるということです。

行と列が有効かどうかを確認することで、dropMimeData(再実装中)の「挿入」ドロップを無視できることを知っています(既存のアイテムへのドロップでは、行と列が-1に設定され、親が現在のアイテムに設定されています)。私はこれをやっています。しかし、私はこれらのドロップを取得したくないです。つまり。アイテムの間にではなく、常に上のアイテムまたは下のアイテムのいずれかをドロップするようにしたいと思います。

何か案は?

アドバイスをありがとう、ジャイルズ

4

3 に答える 3

3

dragEnterEventカスタムビューでメソッドを再実装して、ドラッグ入力イベントをキャッチする必要があります。Qtドキュメントの例は次のとおりです。

void Window::dragEnterEvent(QDragEnterEvent *event)
{
    if (event->mimeData()->hasFormat("text/plain"))
        event->acceptProposedAction();
}

あなたの場合、おそらくイベントのxとyの位置を、最も近いアイテムまたは類似のもののxとyの位置と比較し、その情報に基づいて提案されたアクションを拒否または受け入れる必要があります。

QAbstractItemModel::dropMimeDataドキュメントから:

データを挿入する適切な場所を提供するのは、ビューの責任です。

これは、あなたのような基礎となるモデルによってサポートされているものでない場合、ビューがドロップを拒否する必要があることを意味すると解釈しました。

于 2011-08-05T04:21:50.323 に答える
3

Qt 5.4の時点で(そしてこれはQt 4.8でも当てはまると思います)、に設定するDragDropOverwriteModetrue、ドラッグは既存のアイテムにのみドロップ可能になり、「アイテムの上/下」のドロップターゲットが表示されなくなります。

また、質問が主張するものとは異なり、デフォルトでにDragDropOverwriteMode設定されているため(チェックしていませんが、新しいQtバージョンである可能性があります)、手動で設定する必要があります。falseQTreeViewtrue

ただし、アイテムをドロップできる位置を計算できると便利です。たとえば、QTreeViewでは、ドラッグしたものをアイテムの左マージン、つまり下の赤い領域にドロップすることはできません。

QTreeViewの無効なドロップ領域

無効な赤い領域に何かがドロップされた場合、引数をに設定してdropMimeData呼び出されます。したがって、事前に「ここにドロップできない」カーソルをユーザーに表示して、ユーザーがそこにドロップできないことを認識しておくと便利です。Qtは、ドラッグ中に無効な領域でマウスカーソルを変更することを実装していません(Qt 5.4以降)が、次のように行うことができます。parentNULLignoredragMoveEvent

bool SubclassedTreeView::dropResultsInValidIndex(const QPoint& pos)
{
    QTreeWidgetItem* item = itemAt(pos);
    if (item == NULL || !indexFromItem(item).isValid())
        return false;
    return visualRect(indexFromItem(item)).adjusted(-1, -1, 1, 1).contains(pos, false);
}

virtual void SubclassedTreeView::dragMoveEvent(QDragMoveEvent* event)
{
    QTreeWidget::dragMoveEvent(event);
    if (!event->isAccepted())
        return;

    if (dropResultsInValidIndex(event->pos()))
        event->accept();
    else
        event->ignore(); //Show 'forbidden' cursor.
}

virtual bool SubclassedTreeView::dropMimeData(QTreeWidgetItem* parent, int index, const QMimeData* data, Qt::DropAction action)
{
    Q_UNUSED(index);
    //Modify the following action and data format checks to suit your needs:
    if (parent == NULL || action != Qt::CopyAction || !data->hasFormat("my/preferred-type"))
        return false;

    QModelIndex modelIndex = indexFromItem(parent);
    //modelIndex is where the data is dropped onto. Implement your custom drop action here...

    return true;
}

上記のコードには、ソースvisualRect….adjusted(-1, -1, 1, 1)から盗まれた小さな部分が含まれていQAbstractItemViewPrivate::positionます。実際には、この関数のソースを使用して、アイテムの上書き/挿入/無効領域を計算することもQAbstractItemViewPrivate::positionできfalseます。

于 2016-03-22T11:58:35.950 に答える
0

ドロップインジケーター()の現在位置に基づいた解決策を提案したいと思いQAbstractItemView::DropIndicatorPositionます。実装は非常に簡単ですが、残念ながらドロップインジケーターを表示する必要があります。ただし、これは場合によっては許容できる場合があります。

TreeView::TreeView(QWidget* parent) : QTreeView(parent)
{
    setDropIndicatorShown(true);
}

void TreeView::dragMoveEvent(QDragMoveEvent* event)
{
    QTreeView::dragMoveEvent(event);

    if (dropIndicatorPosition() != QTreeView::OnItem)
        event->setDropAction(Qt::IgnoreAction);
}
于 2020-10-04T22:27:38.280 に答える