#ifndef WIDGET_H
#define WIDGET_H
#include <QWidget>
namespace Ui {
class Widget;
}
class Widget : public QWidget
{
Q_OBJECT
public:
explicit Widget(QWidget *parent = nullptr);
~Widget();
private:
Ui::Widget *ui;
};
#endif // WIDGET_H
#include "widget.h"
#include "ui_widget.h"
#include <QSplitter>
#include "container.h"
Widget::Widget(QWidget *parent) :
QWidget(parent),
ui(new Ui::Widget)
{
ui->setupUi(this);
QSplitter * splitter = new QSplitter(this);
splitter->addWidget(new Container(this));
splitter->addWidget(new Container(this));
ui->verticalLayout->addWidget(splitter);
}
Widget::~Widget()
{
delete ui;
}
#ifndef PIXMAPMIME_H
#define PIXMAPMIME_H
#include <QMimeData>
#include <QPixmap>
class PixmapMime : public QMimeData
{
Q_OBJECT
public:
explicit PixmapMime(QPixmap pix,QPoint offset,QString description);
QPixmap pix() const;
QPoint offset() const;
signals:
public slots:
private:
QPixmap mPix;
QPoint mOffset;
QString description;
QStringList mimeFormats;
// QMimeData interface
public:
QStringList formats() const override;
protected:
QVariant retrieveData(const QString &mimetype, QVariant::Type preferredType) const override;
};
#endif // PIXMAPMIME_H
#include "pixmapmime.h"
PixmapMime::PixmapMime(QPixmap pix,QPoint offset,QString description) :
mPix(pix),mOffset(offset),description(description)
{
mimeFormats << "text/html" << "text/plain";
}
QPixmap PixmapMime::pix() const
{
return mPix;
}
QPoint PixmapMime::offset() const
{
return mOffset;
}
QStringList PixmapMime::formats() const
{
return mimeFormats;
}
QVariant PixmapMime::retrieveData(const QString &mimetype, QVariant::Type preferredType) const
{
if(mimetype == "text/plain"){
return description;
}else if(mimetype == "text/html"){
QString htmlString ;
htmlString.append( "<html><p>" );
htmlString.append(description) ;
htmlString.append("</p></html>");
return htmlString;
}else {
return QMimeData::retrieveData(mimetype,preferredType);
}
}
#ifndef CONTAINER_H
#define CONTAINER_H
#include <QWidget>
class Container : public QWidget
{
Q_OBJECT
public:
explicit Container(QWidget *parent = nullptr);
signals:
public slots:
// QWidget interface
protected:
void mousePressEvent(QMouseEvent *event) override;
void mouseMoveEvent(QMouseEvent *event) override;
void dragEnterEvent(QDragEnterEvent *event) override;
void dragMoveEvent(QDragMoveEvent *event) override;
void dragLeaveEvent(QDragLeaveEvent *event) override;
void dropEvent(QDropEvent *event) override;
void paintEvent(QPaintEvent *event) override;
private:
QPoint startPos;
};
#endif // CONTAINER_H
#include "container.h"
#include <QLabel>
#include <QPainter>
#include <QMouseEvent>
#include <QApplication>
#include <QDataStream>
#include <QMimeData>
#include <QDrag>
#include <QDebug>
#include "pixmapmime.h"
Container::Container(QWidget *parent) : QWidget(parent)
{
setMinimumSize(150,150);
setAcceptDrops(true);
QLabel * qtIcon = new QLabel(this);
qtIcon->setPixmap(QPixmap(":/images/qt.png"));
qtIcon->move(20,20);
qtIcon->show();
qtIcon->setAttribute(Qt::WA_DeleteOnClose);
QLabel * cppIcon = new QLabel(this);
cppIcon->setPixmap(QPixmap(":/images/cpp.png"));
cppIcon->move(150,20);
cppIcon->show();
cppIcon->setAttribute(Qt::WA_DeleteOnClose);
QLabel * terminalIcon = new QLabel(this);
terminalIcon->setPixmap(QPixmap(":/images/terminal.png"));
terminalIcon->move(20,150);
terminalIcon->show();
terminalIcon->setAttribute(Qt::WA_DeleteOnClose);
}
void Container::mousePressEvent(QMouseEvent *event)
{
if (event->button() == Qt::LeftButton)
startPos = event->pos();
QWidget::mousePressEvent(event);
}
void Container::mouseMoveEvent(QMouseEvent *event)
{
if (event->buttons() & Qt::LeftButton) {
int distance = (event->pos() - startPos).manhattanLength();
if (distance >= QApplication::startDragDistance())
{
QLabel * child = static_cast<QLabel *>(childAt(event->pos()));
if(!child)
return;
QPixmap mPixmap = * child->pixmap();
/*
QByteArray ba;
QDataStream dataStream(&ba,QIODevice::WriteOnly);
dataStream << mPixmap << QPoint(event->pos() - child->pos());
QMimeData * mimeData = new QMimeData;
mimeData->setData("application/x-qtcustomitem",ba);
*/
PixmapMime * mimeData = new PixmapMime(mPixmap,
QPoint(event->pos() - child->pos()),
"Item icon");
QDrag * drag = new QDrag(this);
drag->setMimeData(mimeData);
drag->setPixmap(mPixmap);
drag->setHotSpot(event->pos() - child->pos());
//Blur the original label
QPixmap tempPix = mPixmap;
QPainter painter(&tempPix);
painter.fillRect(tempPix.rect(),QColor(127, 127, 127, 127));
child->setPixmap(tempPix);
//Call to drag->exec() is blocking
if(drag->exec(Qt::MoveAction | Qt::CopyAction,Qt::CopyAction) == Qt::MoveAction){
//Move data
qDebug()<< "Moving data";
child->close();
}else{
//Copy action
child->setPixmap(mPixmap);
qDebug() << "Copying data";
}
}
}
}
void Container::dragEnterEvent(QDragEnterEvent *event)
{
if (qobject_cast<const PixmapMime *>(event->mimeData())) {
if (event->source() == this) {
event->setDropAction(Qt::MoveAction);
event->accept();
//event->ignore();
} else {
event->acceptProposedAction();
}
}else{
event->ignore();
}
}
void Container::dragMoveEvent(QDragMoveEvent *event)
{
if (qobject_cast<const PixmapMime *>(event->mimeData())) {
if (event->source() == this) {
event->setDropAction(Qt::MoveAction);
event->accept();
//event->ignore();
} else {
event->acceptProposedAction();
}
}else{
event->ignore();
}
}
void Container::dragLeaveEvent(QDragLeaveEvent *event)
{
QWidget::dragLeaveEvent(event);
}
void Container::dropEvent(QDropEvent *event)
{
const PixmapMime * mimeData =
qobject_cast<const PixmapMime *> (event->mimeData());
if(mimeData){
QPixmap mPixmap = mimeData->pix();
QPoint offset = mimeData->offset();
QLabel * newLabel = new QLabel(this);
newLabel->setPixmap(mPixmap);
newLabel->move(event->pos() - offset);
newLabel->show();
newLabel->setAttribute(Qt::WA_DeleteOnClose);
if (event->source() == this) {
event->setDropAction(Qt::MoveAction);
event->accept();
//event->ignore();
} else {
event->acceptProposedAction();
}
}
else{
event->ignore();
}
/*
if (event->mimeData()->hasFormat("application/x-qtcustomitem")) {
// QByteArray ba = event->mimeData()->data("application/x-qtcustomitem");
// QDataStream dataStream(&ba,QIODevice::ReadOnly);
// QPixmap mPixmap;
// QPoint offset;
// dataStream >> mPixmap >> offset;
QLabel * newLabel = new QLabel(this);
newLabel->setPixmap(mPixmap);
newLabel->move(event->pos() - offset);
newLabel->show();
newLabel->setAttribute(Qt::WA_DeleteOnClose);
if (event->source() == this) {
event->setDropAction(Qt::MoveAction);
event->accept();
//event->ignore();
} else {
event->acceptProposedAction();
}
}else{
event->ignore();
}
*/
}
void Container::paintEvent(QPaintEvent *event)
{
QPainter painter(this);
painter.drawRoundRect(0,5,width()-10, height()-10,3,3);
QWidget::paintEvent(event);
}