Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Dragging a QWidget in QT 5

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?

like image 719
Leonid Bor Avatar asked Aug 18 '13 12:08

Leonid Bor


People also ask

How do you drag in Qt?

To start a drag, create a QDrag object, and call its exec() function. In most applications, it is a good idea to begin a drag and drop operation only after a mouse button has been pressed and the cursor has been moved a certain distance.

How do I change my QWidget position?

Use QWidget::move() to set the position, QWidget::resize() to set the size and reimplement the parent's resizeEvent() handler if you need to re-position the widgets if their parent resizes. Show activity on this post. You just need to create your widget, indicate its parent QWidget and then display it.

How do I resize a layout in Qt?

Once you have add your layout with at least one widget in it, select your window and click the "Update" button of QtDesigner. The interface will be resized at the most optimized size and your layout will fit the whole window. Then when resizing the window, the layout will be resized in the same way.


2 Answers

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.

like image 183
Greenflow Avatar answered Sep 27 '22 22:09

Greenflow


do a trick then you can able to drag QWidget also,

QPixmap *widgetPixmap = new QPixmap;
yourWidget->render(widgetPixmap); // rendering the current widget to t_iconTPixmap

Now use this widgetPixmap as the pixmap for yourDragObject->setPixmap();

example,

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()); 

    QPixmap *widgetPixmap = new QPixmap;
    yourWidget->render(widgetPixmap);

    drag->setMimeData(mimeData);
    drag->setPixmap(widgetPixmap);

    Qt::DropAction dropAction = drag->exec();
    ...
   }
}
like image 33
Akhil V Suku Avatar answered Sep 27 '22 21:09

Akhil V Suku