03 ProjectListWidget *source =

04 qobject_cast(event->source());

05 if (source && source != this) {

07 event->setDropAction(Qt::MoveAction);

08 event->accept();

09 }

10 }

Программный код функции dragMoveEvent() идентичен тому, что мы делали в функции dragEnterEvent(). Он необходим, потому что нам приходится переопределять реализацию этой функции в классе QListWidget (в действительности в классе QAbstractItemView).

01 void ProjectListWidget::dropEvent(QDropEvent *event)

02 {

03 ProjectListWidget *source =

04 qobject_cast(event->source());

05 if (source && source != this) {

06 addItem(event->mimeData()->text());

07 event->setDropAction(Qt::MoveAction);

08 event->accept();

09 }

10 }

В DropEvent() мы используем функцию QMimeData::text() для получения перенесенного текста и создаем элемент с этим текстом. Нам также необходимо воспринять данное событие как «операцию перетаскивания», чтобы указать исходному виджету на то, что он может теперь удалить первоначальную версию перенесенного элемента.

«Drag-and-drop» — мощный механизм передачи данных между приложениями. Однако в некоторых случаях его можно реализовать, не используя предусмотренные в Qt средства механизма «drag-and-drop». Если нам требуется переносить данные внутри одного виджета некоторого приложения, во многих случаях мы можем просто переопределить функции mousePressEvent() и mouseReleaseEvent().

<p>Поддержка пользовательских типов переносимых объектов</p>

До сих пор в представленных примерах мы полагались на поддержку QMimeData распространенных типов MIME. Так, мы вызывали QMimeData::setText() для создания объекта переноса текста и использовали QMimeData:urls() для получения содержимого объекта переноса типа text/uri-list. Если мы хотим перетаскивать обычный текст, текст в формате HTML, изображения, адреса URL или цвета, мы можем спокойно использовать класс QMimeData. Но если мы хотим перетаскивать пользовательские данные, необходимо сделать выбор между следующими альтернативами:

1. Мы можем обеспечить произвольные данные в виде массива QByteArray, используя функцию QMimeData::setData(), и извлекать их позже, используя функцию QMimeData::data().

2. Мы можем создать подкласс QMimeData и переопределить функции formats() и retrieveData() для обработки наших пользовательских типов данных.

3. Для выполнения операций механизма «drag-and-drop» в рамках одного приложения мы можем создать подкласс QMimeData и хранить данные в любых структурах данных.

Первый подход не требует никаких подклассов, но имеет некоторые недостатки: нам необходимо преобразбвать наши структуры данных в тип QByteArray, даже если переносимый объект не принимается, а если требуется обеспечить несколько MIME—типов, чтобы можно было хорошо взаимодействовать с самыми разными приложениями, нам придется сохранять несколько копий данных (по одной на каждый тип MIME). Если данные имеют большой размер, это может излишне замедлять работу приложения. При использовании второго и третьего подходов можно избежать или свести к минимуму эти проблемы. В этом случае мы получаем полное управление и можем использовать эти два подхода совместно.

Для демонстрации этих подходов мы покажем, как можно добавить возможности технологии «drag-and-drop» в виджет QTableWidget. Будет поддерживаться перенос следующих типов MIME: text/plain, text/html и text/csv. При применении первого подхода инициирование переноса выглядит следующим образом:

01 void MyTableWidget::mouseMoveEvent(QMouseEvent *event)

02 {

03 if (event->buttons() & Qt::LeftButton) {

04 int distance = (event->pos() - startPos).manhattanLength();

05 if(distance >= QApplication::startDragDistance())

06 startDrag();

07 }

08 QTableWidget::mouseMoveEvent(event);

09 }

Перейти на страницу:

Похожие книги