Перетаскивание QWidget в QT 5

Я должен сделать что-то вроде интерфейса iOS, 3x3 поле значков, которые можно перетащить, чтобы изменить их положение, а затем запомнить его в XML-файле.

Я решил использовать класс Grid (QWidget является родительским) в качестве контейнера и мой собственный класс, унаследованный от QWidget, в качестве элементов.

теперь я пытаюсь узнать, как выполнить drag & drop для QWidget, но кажется, что вы можете только упасть на QWidget, но его невозможно перетащить.

Это невозможно? Как мне передвинуть эту штуку?

3 ответов


перетаскивание виджета не так просто. Много кодирования вы должны сделать сами.

С 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();
        ...
    }
}

это означает, что когда ваш виджет получает сообщение о том, что его нужно перетащить, например, как с помощью мыши, он должен создать объект QDrag.

в объекте QDrag вы можете установить pixmap, который представляет ваш перетаскиваемый виджет. Если вы спрячете свой виджет в этот момент, это выглядит так, как будто ваш указатель мыши "взял" виджет.

кроме того, вам нужен объект QMimeData. В этом вы можете поместить все виды данных, которые описывает ваш виджет. В вашем случае то, что позволяет идентифицировать ваш виджет. Потому что, и здесь приходит трудная часть: вы должны сделать движение самостоятельно.

виджет, который является родителем сетки, получает событие drop и считывает данные mime, которые виджет хочет мне переместить. Из QDropEvent он получает точку, в которую должен быть перемещен виджет. Это то, что вам нужно закодировать: фактическое перемещение в вашем макете сетки. И не забудьте обновить xml.


сделать трюк, то вы можете в состоянии перетащить QWidget также,

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

теперь использовать это widgetPixmap как pixmap для yourDragObject->setPixmap();

например,

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

Qt wiki содержит пример QtQuick о том, как эмулировать интерфейс значков iOS с менее чем 80 строками кода.

вы можете найти здесь.