2

我已经实现了以下拖放方法

void mousePressEvent(QMouseEvent *event);
void dragEnterEvent(QDragEnterEvent *event);
void dragMoveEvent(QDragMoveEvent *event);
void dropEvent(QDropEvent *event);
void startDrag(Qt::DropActions supportedActions);

我有一个 QListView 并使用 setIndexWidget() 在每个模型索引处显示一个自定义小部件。我正在尝试使用拖放来排列列表视图中的项目,但是列表视图中的项目排列不正确,我编写了以下代码:-

MyListView::MyListView(QWidget *parent) :
    QListView(parent)
{
    setSelectionMode(QAbstractItemView::SingleSelection);
    setDragEnabled(true);
    setAcceptDrops(true);
    setDragDropMode(QAbstractItemView::InternalMove);
    setDefaultDropAction(Qt::MoveAction);
    setDropIndicatorShown(true);
    setDragDropOverwriteMode(true);
    setMovement(QListView::Snap);
    setFlow(QListView::TopToBottom);
//    setStyleSheet("QListView::item {"
//                  "height: 50px;"
//                  "border: 1px solid black;}");
}

void MyListView::setModel(QAbstractItemModel *model)
{
    QListView::setModel(model);

    for (int i=0; i<model->rowCount(); i++)
    {
        QModelIndex index = model->index(i,0);
        ListWidgetItem *widget = new ListWidgetItem;
        widget->setIndex(i);;
        setIndexWidget(index,widget);
    }
}

void MyListView::mousePressEvent(QMouseEvent *event)
{
    QModelIndex i = indexAt(event->pos());
    if (event->button() ==  Qt::LeftButton)
    {
        ListWidgetItem *item = dynamic_cast<ListWidgetItem *>(childAt(event->pos()));

        if (!item)
            return;

        y = event->pos().y()-item->pos().y();

        QModelIndex indx = indexAt(event->pos());
        currentPixmap = QPixmap::grabWidget(item);
        dragPoint = event->pos();
        if (event->pos().x() < 25 && indx.row() >= 0)
            startDrag(Qt::MoveAction);
    }
}

void MyListView::dragEnterEvent(QDragEnterEvent *event)
{
   if (event->mimeData()->hasFormat("application/x-QListView-DragAndDrop"))
   {
       event->accept();
   }
    else
        event->ignore();
}

void MyListView::dragMoveEvent(QDragMoveEvent *event)
{
    ListWidgetItem *item = dynamic_cast<ListWidgetItem *>(childAt(event->pos()));
    if(!item)
        return;

    itemList.append(item);

    foreach (ListWidgetItem *widget,itemList)
    {
        if (widget == item)
            widget->setStyleSheet("#ListWidget { border-top: 2px solid red; }");
        else
            widget->setStyleSheet("#ListWidget { border-top: 0px solid black; }");
    }
    if (event->mimeData()->hasFormat("application/x-QListView-DragAndDrop"))
    {
        event->setDropAction(Qt::MoveAction);
        event->accept();
    } else
        event->ignore();
}

void MyListView::dropEvent(QDropEvent *event)
{
    if (event->mimeData()->hasFormat("application/x-QListView-DragAndDrop")) {
        QByteArray itemData = event->mimeData()->data("application/x-QListView-DragAndDrop");
        QDataStream dataStream(&itemData,QIODevice::ReadOnly);

        QPoint itemPoint;
        dataStream >> itemPoint;

        ListWidgetItem *item = dynamic_cast<ListWidgetItem *> (childAt(itemPoint));
        if(!item)
            return;

        QModelIndex index = indexAt(event->pos());
        int row = index.row();
        model()->insertRows(row,1);

        QModelIndex idx =model()->index(row,0);
        setIndexWidget(idx,item);

        if (event->source() == this) {
            event->setDropAction(Qt::MoveAction);
            foreach (ListWidgetItem *widget,itemList)
            {
                widget->setStyleSheet("#ListWidget { border-top: 0px solid black; }");
            }
            itemList.clear();
//            model()->removeRow(n+1);

            event->accept();
        }
    } else{
        event->ignore();
    }
}

void MyListView::startDrag(Qt::DropActions supportedActions)
{
    QByteArray itemData;
    QDataStream dataStream(&itemData, QIODevice::WriteOnly);

    ListWidgetItem *item = dynamic_cast<ListWidgetItem *>(childAt(dragPoint));

    dataStream << dragPoint;

    QMimeData *mimeData = new QMimeData;
    mimeData->setData("application/x-QListView-DragAndDrop", itemData);

    drag = new QDrag(this);
    drag->setMimeData(mimeData);
    drag->setHotSpot(mapToParent(QPoint(item->x(),y)));
    drag->setPixmap(currentPixmap);

    QModelIndex indx = indexAt(dragPoint);
    if (drag->exec(Qt::MoveAction | Qt::CopyAction) == Qt::MoveAction)
     {
        model()->removeRow(indx.row());
     }

}

我已经搜索但没有得到任何适当的解决方案。谢谢

4

1 回答 1

3

你看过 QAbstractItemView 的 DragDropMode 吗?http://qt-project.org/doc/qt-4.8/qabstractitemview.html#dragDropMode-prop

听起来好像这就是你想要达到的目标。

于 2012-10-29T12:59:49.137 回答