PDA

View Full Version : drag and drop QLabels



tonio
4th June 2009, 15:20
Hello,

I'm trying to understand a strange problem, if it is a problem, when doing a drag and drop over QLables in a QFrame.
I'm using the example of Qt about the drag and drop "Draggable Icons".
I modified just a little bit the code in the constructor DragWidget :: DragWidget(QWidget *parent) and in the
void DragWidget::mousePressEvent(QMouseEvent *event) method.

In the constructor I've put this 3 lines for each label:

boatIcon->setObjectName(QString("BOAT"));

carIcon->setObjectName(QString("CAR"));

houseIcon->setObjectName(QString("HOUSE"));

In the mouse handler method I've put this line:

qDebug("child name %s", child->objectName().toLatin1().data());

So as you see nothing special. But when I'm pressing with the mouse over the labels there is no name object, more precisely qDebug shows only the first time the name and after the objetName() returns empty string ....

Here is the entire code of the modified example:

dragwidget.h



#ifndef DRAGWIDGET_H
#define DRAGWIDGET_H

#include <QFrame>

QT_BEGIN_NAMESPACE
class QDragEnterEvent;
class QDropEvent;
QT_END_NAMESPACE

//! [0]
class DragWidget : public QFrame
{
public:
DragWidget(QWidget *parent=0);

protected:
void dragEnterEvent(QDragEnterEvent *event);
void dragMoveEvent(QDragMoveEvent *event);
void dropEvent(QDropEvent *event);
void mousePressEvent(QMouseEvent *event);
};
//! [0]

#endif



dragwidget.cpp



#include <QtGui>

#include "dragwidget.h"

//! [0]
DragWidget::DragWidget(QWidget *parent)
: QFrame(parent)
{
setMinimumSize(200, 200);
setFrameStyle(QFrame::Sunken | QFrame::StyledPanel);
setAcceptDrops(true);

QLabel *boatIcon = new QLabel(this);
boatIcon->setObjectName(QString("BOAT")); //<---- here
boatIcon->setPixmap(QPixmap(":/images/boat.png"));
boatIcon->move(20, 20);
boatIcon->show();
boatIcon->setAttribute(Qt::WA_DeleteOnClose);

QLabel *carIcon = new QLabel(this);
carIcon->setObjectName(QString("CAR")); //<---- here
carIcon->setPixmap(QPixmap(":/images/car.png"));
carIcon->move(120, 20);
carIcon->show();
carIcon->setAttribute(Qt::WA_DeleteOnClose);

QLabel *houseIcon = new QLabel(this);
houseIcon->setObjectName(QString("HOUSE")); //<---- here
houseIcon->setPixmap(QPixmap(":/images/house.png"));
houseIcon->move(20, 120);
houseIcon->show();
houseIcon->setAttribute(Qt::WA_DeleteOnClose);
}
//! [0]

void DragWidget::dragEnterEvent(QDragEnterEvent *event)
{
if (event->mimeData()->hasFormat("application/x-dnditemdata")) {
if (event->source() == this) {
event->setDropAction(Qt::MoveAction);
event->accept();
} else {
event->acceptProposedAction();
}
} else {
event->ignore();
}
}

void DragWidget::dragMoveEvent(QDragMoveEvent *event)
{
if (event->mimeData()->hasFormat("application/x-dnditemdata")) {
if (event->source() == this) {
event->setDropAction(Qt::MoveAction);
event->accept();
} else {
event->acceptProposedAction();
}
} else {
event->ignore();
}
}

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

QPixmap pixmap;
QPoint offset;
dataStream >> pixmap >> offset;

QLabel *newIcon = new QLabel(this);
newIcon->setPixmap(pixmap);
newIcon->move(event->pos() - offset);
newIcon->show();
newIcon->setAttribute(Qt::WA_DeleteOnClose);

if (event->source() == this) {
event->setDropAction(Qt::MoveAction);
event->accept();
} else {
event->acceptProposedAction();
}
} else {
event->ignore();
}
}

//! [1]
void DragWidget::mousePressEvent(QMouseEvent *event)
{
QLabel *child = static_cast<QLabel*>(childAt(event->pos()));
if (!child)
return;

qDebug("child name %s", child->objectName().toLatin1().data());

QPixmap pixmap = *child->pixmap();

QByteArray itemData;
QDataStream dataStream(&itemData, QIODevice::WriteOnly);
dataStream << pixmap << QPoint(event->pos() - child->pos());
//! [1]

//! [2]
QMimeData *mimeData = new QMimeData;
mimeData->setData("application/x-dnditemdata", itemData);
//! [2]

//! [3]
QDrag *drag = new QDrag(this);
drag->setMimeData(mimeData);
drag->setPixmap(pixmap);
drag->setHotSpot(event->pos() - child->pos());
//! [3]

QPixmap tempPixmap = pixmap;
QPainter painter;
painter.begin(&tempPixmap);
painter.fillRect(pixmap.rect(), QColor(127, 127, 127, 127));
painter.end();

child->setPixmap(tempPixmap);

if (drag->exec(Qt::CopyAction | Qt::MoveAction, Qt::CopyAction) == Qt::MoveAction)
child->close();
else {
child->show();
child->setPixmap(pixmap);
}
}


main.cpp




#include <QApplication>
#include <QHBoxLayout>
#include "dragwidget.h"

int main(int argc, char *argv[])
{
Q_INIT_RESOURCE(draggableicons);

QApplication app(argc, argv);

QWidget mainWidget;
QHBoxLayout *horizontalLayout = new QHBoxLayout;
horizontalLayout->addWidget(new DragWidget);
horizontalLayout->addWidget(new DragWidget);

mainWidget.setLayout(horizontalLayout);
mainWidget.setWindowTitle(QObject::tr("Draggable Icons"));
mainWidget.show();

return app.exec();
}



If someone has an explanation, I'll be happy to hear it :)

Best regards,

Anton

PS. The images needed in this example are like attached files, you should put them in a "image" directory in the directory where the source files for this example are.