Dragging a QWidget in QT 5

Leonid Bor picture Leonid Bor · Aug 18, 2013 · Viewed 14.7k times · Source

I have to make something like the iOS interface, 3x3 field of icons that can be dragged to change their position, and then remember it in an XML file.

I decided to use Grid class (QWidget is parent) as a container and my own class, inherited from QWidget, as elements.

Now I'm trying to learn how to perform a drag & drop for QWidget, but it seems like you are only able to drop onto a QWidget, but it's impossible to drag it.

Is it impossible? How do I move this thing?

Answer

Greenflow picture Greenflow · Aug 18, 2013

Dragging a widget isn't that easy. Plenty of coding you have to do yourself.

From the Qt Docs:

void MainWindow::mousePressEvent(QMouseEvent *event)
{
    if (event->button() == Qt::LeftButton
        && iconLabel->geometry().contains(event->pos())) {

        QDrag *drag = new QDrag(this);
        QMimeData *mimeData = new QMimeData;

        mimeData->setText(commentEdit->toPlainText());
        drag->setMimeData(mimeData);
        drag->setPixmap(iconPixmap);

        Qt::DropAction dropAction = drag->exec();
        ...
    }
}

This means, when your widget receives a message that it is to be dragged, e.g. like with a mousepress, it has to create a QDrag object.

In the QDrag object you can set a pixmap, which represents your dragged widget. If you hide your widget at this point, it looks like as if your mouse pointer 'took' the widget.

Additionally you need a QMimeData object. In this you can put all kinds of data, which describes your widget. In your use case something which allows you to identify your widget. Because, and here comes the difficult part: You have to do the moving yourself.

The widget, which is the grid's parent, receives the drop event and reads from the mime data, which widget wishes to me moved. From the QDropEvent it gets the point where the widget is to be moved. That's what you have to code: The actual repositioning in your grid layout. And don't forget to update the xml.