问题
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?
回答1:
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.
回答2:
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();
...
}
}
回答3:
The Qt wiki contains a QtQuick example on how to emulate the iOS icon interface with less then 80 lines of code.
You can find it here.
来源:https://stackoverflow.com/questions/18299077/dragging-a-qwidget-in-qt-5