[Qt] QtreeWidget Drag&Drop zmiana pozycji

0

Witam.
Próbuję zrobić coś takiego jak jest w liście odtwarzania w winampie, że jak się złapie element i przeciągnie w dół to zamieni się pozycją z tym niższym.
Tylko teraz nie wiem jak użyć tego dragdrop mode, bo on albo duplikuje przeciągnięty element, albo wrzuca element do tego niższego (tworząc z niego rodzica dla przeciąganego elementu).
Proszę o pomoc jak wykonać taką zmianę pozycji.

0

pokaż jak to zrobiłeś!

0
    QTreeWidget *treeWidget = new QTreeWidget(this);
    treeWidget->setColumnCount(2);
    treeWidget->setSortingEnabled(true);
    treeWidget->setIndentation(0);
    treeWidget->setAlternatingRowColors(true);

    treeWidget->setSelectionMode(QAbstractItemView::ExtendedSelection);
    treeWidget->setDragDropMode(QAbstractItemView::DragDrop);
    treeWidget->setAcceptDrops(true);
    treeWidget->setDragEnabled(true);
    treeWidget->setDragDropOverwriteMode(true);
    treeWidget->setDropIndicatorShown(true);

    QStringList headers;
    headers << "Nazwa" << "Czas";
    treeWidget->setHeaderLabels(headers);

    QTreeWidgetItem *track1 = new QTreeWidgetItem(treeWidget);
    track1->setText(0, "track1");
    track1->setText(1, "6minut");

    QTreeWidgetItem *track2 = new QTreeWidgetItem(treeWidget);
    track2->setText(0, "track2");
    track2->setText(1, "3minut");

    QTreeWidgetItem *track3 = new QTreeWidgetItem(treeWidget);
    track3->setText(0, "track3");
    track3->setText(1, "16minut");

wstawiałem też inne atrybuty zamiast QAbstractItemView::DragDrop

ostatnio trafiłem też na temat http://www.qtcentre.org/threads/21225-QTableView-and-changing-row-order-in-model-by-dragging-them?highlight=qtreewidge+drag+and+drop
ale nie wiem jak zastosować ten QHeaderView : (

0

Sorry za sporą zwłokę, ale nie miałem czasu na ten nieco bardziej skąplikowany wątek.

Można to zrobić tak przez podmianę jednej metody wirtualnej (w sumie to w dużej części skopiowałem oryginalny kod QTreeWidget jedynie nieco go modyfikując):

#include <QTreeWidget>

class MyTreeWidget : public QTreeWidget
{
Q_OBJECT
public:
    explicit MyTreeWidget(QWidget *parent = 0);

signals:

public slots:

protected:
    void dropEvent(QDropEvent *event);

private:
    bool dropOnCheck(QDropEvent *event, int *dropRow, QModelIndex *dropIndex);
};

#include "mytreewidget.h"
#include <QDropEvent>

MyTreeWidget::MyTreeWidget(QWidget *parent) :
    QTreeWidget(parent)
{
}

void MyTreeWidget::dropEvent(QDropEvent *event)
{
    // QTreeWidget::dropEvent(event);
    int dropRow;
    QModelIndex dropIndex;

    if (dropOnCheck(event, &dropRow, &dropIndex)) {
        QList<QModelIndex> idxs = selectedIndexes();
        QList<QPersistentModelIndex> indexes;
        for (int i = 0; i < idxs.count(); i++)
            indexes.append(idxs.at(i));

        if (!indexes.contains(dropIndex)) {
            // When removing items the drop location could shift
            QPersistentModelIndex dropRowIndex = model()->index(dropRow, 0, dropIndex);

            // Remove the items
            QList<QTreeWidgetItem *> taken;
            for (int i = indexes.count() - 1; i >= 0; --i) {
                QTreeWidgetItem *parent = itemFromIndex(indexes.at(i));
                if (!parent || !parent->parent()) {
                    taken.append(takeTopLevelItem(indexes.at(i).row()));
                } else {
                    taken.append(parent->parent()->takeChild(indexes.at(i).row()));
                }
            }

            // insert them back in at their new positions
            for (int i = 0; i < indexes.count(); ++i) {
                // Either at a specific point or appended
                if (dropRow == -1) {
                    if (dropIndex.isValid()) {
                        QTreeWidgetItem *parent = itemFromIndex(dropIndex);
                        parent->insertChild(parent->childCount(), taken.takeFirst());
                    } else {
                        insertTopLevelItem(topLevelItemCount(), taken.takeFirst());
                    }
                } else {
                    int r = dropRowIndex.row() >= 0 ? dropRowIndex.row() : dropRow;
                    if (dropIndex.isValid()) {
                        QTreeWidgetItem *parent = itemFromIndex(dropIndex);
                        parent->insertChild(qMin(r, parent->childCount()), taken.takeFirst());
                    } else {
                        insertTopLevelItem(qMin(r, topLevelItemCount()), taken.takeFirst());
                    }
                }
            }


            event->setDropAction(Qt::CopyAction);
            event->accept();
            return;
        }
    }
    QTreeWidget::dropEvent(event);

}

bool MyTreeWidget::dropOnCheck(QDropEvent *event, int *dropRow, QModelIndex *dropIndex)
{
    if (event->isAccepted())
        return false;

    QModelIndex index =  indexAt(event->pos());

    if (supportedDropActions() & event->dropAction()) {
        int row = -1;
        //int col = -1;
        if (index != rootIndex() && index.isValid()) {
            QRect rect = visualRect(index);
            qreal criticalY = rect.center().y();

            if (event->pos().y()<=criticalY) {
                row = index.row();
                //col = index.column();
                index = index.parent();
            } else {
                row = index.row() + 1;
                //col = index.column();
                index = index.parent();
            }
            *dropIndex = index;
            *dropRow = row;
            // *dropCol = col;

            return true;
        }
    }
    return false;
}

Działa, ale nie daje gwarancji, że w każdym wypadku (sam się musiałem trochę podszkolić).

0

Wielkie dzięki ! ;-)
Wszystko fajnie działa : )
Pozdrawiam.
Temat można zamknąć.

1 użytkowników online, w tym zalogowanych: 0, gości: 1