Qt - Как показать изображение / значок / данные при перетаскивании элемента? - PullRequest
0 голосов
/ 10 мая 2018

У меня есть приложение, в котором я могу перетащить элемент в QGraphicsScene и создать новый объект в зависимости от текста элемента, но как я могу изменить отображаемые данные при перемещении вокруг элемента?

например, вместо текста я хочу показать значок:

enter image description here

У меня есть список с некоторыми itens:

OptionList::OptionList(QWidget *parent) : QListWidget(parent)
{
    this->setDragEnabled(true);
    this->setDropIndicatorShown(true);
    this->setSelectionMode(QAbstractItemView::SingleSelection);
    this->setDefaultDropAction(Qt::CopyAction);
    this->setViewMode(QListView::ListMode);

    for(const QString &color : {"Blue", "Red", "Green", "Yellow"})
    {
        OptionItem *item = new OptionItem;
        item->setText(color);
        item->setFlags(Qt::ItemIsEnabled| Qt::ItemIsSelectable| Qt::ItemIsDragEnabled);
        addItem(item);
    }
}

Я бросаю itens на сцену, чтобы создать новый объект:

MyScene::MyScene()
{
    setBackgroundBrush(Qt::lightGray);
}

void MyScene::dragEnterEvent(QGraphicsSceneDragDropEvent *event)
{
    if(event->mimeData()->hasFormat("application/x-qabstractitemmodeldatalist"))
    event->setAccepted(true);
}

void MyScene::dragMoveEvent(QGraphicsSceneDragDropEvent *event)
{
    if(event->mimeData()->hasFormat("application/x-qabstractitemmodeldatalist"))
    event->setAccepted(true);
}

void MyScene::dropEvent(QGraphicsSceneDragDropEvent *event)
{
    QByteArray encoded = event->mimeData()->data("application/x-qabstractitemmodeldatalist");
    QDataStream stream(&encoded, QIODevice::ReadOnly);

    QStringList colors;

    while (!stream.atEnd())
    {
        int row, col;
        QMap<int,  QVariant> roleDataMap;
        stream >> row >> col >> roleDataMap;
        colors << roleDataMap[Qt::DisplayRole].toString();
    }

    QPointF posView = event->scenePos() ;

    for(const QString & color: colors)
    {
        Block *newBlock = new Block(color);
        newBlock->setPos(posView);
        addItem(newBlock);
    }
}

Затем я создал класс OptionItem, производный от QListWidgetItem, и повторно реализовал mousePressEvent, mouseMoveEvent и mouseReleaseEvent

OptionItem::OptionItem()
{

}

void OptionItem::mousePressEvent(QGraphicsSceneMouseEvent *event)
{
    event->setAccepted(true);
}

void OptionItem::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
{
    QDrag *drag = new QDrag(event->widget());

    QMimeData *mime = new QMimeData;

    QImage image(":/images/MyIcon_icon.png");
    mime->setImageData(image);

    drag->setMimeData(mime);
    drag->setPixmap(QPixmap::fromImage(image));
    drag->setHotSpot(QPoint(15, 30));

    drag->exec();

    event->setAccepted(true);
}

void OptionItem::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
{
    event->setAccepted(true);
}

Я пытался следовать примеру робота перетаскивания в Qt Creator, но это не то же самое

Кажется, что изображение появляется очень быстро, когда я начинаю перетаскивать элемент

Есть ли способ показать значок при перетаскивании элемента на протяжении всей операции?

1 Ответ

0 голосов
/ 10 мая 2018

Классы, которые наследуются от QAbstractItemView, поддерживают перетаскивание по умолчанию, поэтому они уже реализовали методы, вместо этого в приведенном вами примере показано, как реализовать эту функцию для некоторого класса, в котором ее нет, задача в вашем случае проста , вы должны перезаписать метод startDrag из QListWidget.

optionilist.h

#ifndef OPTIONLIST_H
#define OPTIONLIST_H

#include <QListWidget>


class OptionList: public QListWidget{
public:
    OptionList(QWidget* parent=nullptr);

protected:
    void startDrag(Qt::DropActions supportedActions);
};

#endif // OPTIONLIST_H

optionlist.cpp

#include "optionlist.h"

#include <QDrag>

OptionList::OptionList(QWidget *parent): QListWidget(parent){

    setDragEnabled(true);
    setDropIndicatorShown(true);
    setSelectionMode(QAbstractItemView::SingleSelection);
    setDefaultDropAction(Qt::CopyAction);
    setViewMode(QListView::ListMode);

    for(const QString &color : {"Blue", "Red", "Green", "Yellow"}){
        QListWidgetItem *blue = new QListWidgetItem;
        blue->setText(color);
        blue->setFlags(Qt::ItemIsEnabled| Qt::ItemIsSelectable| Qt::ItemIsDragEnabled);
        addItem(blue);
    }
}

void OptionList::startDrag(Qt::DropActions supportedActions){
    if(supportedActions & Qt::CopyAction){
        QList<QListWidgetItem *> m_items = selectedItems();
        if(m_items.isEmpty())
            return;
        QMimeData *data = mimeData(m_items);
        QDrag *drag = new QDrag(this);
        QPixmap pixmap(":/images/MyIcon_icon.png");
        drag->setPixmap(pixmap);
        drag->setMimeData(data);
        drag->setHotSpot(pixmap.rect().center());
        drag->exec(Qt::CopyAction);
    }
    else
        QListWidget::startDrag(supportedActions);

}

Полный код можно найти по следующей ссылке .

...