Чтение онлайн

на главную - закладки

Жанры

QT 4: программирование GUI на С++

Саммерфилд Марк

Шрифт:

01 void ProjectListWidget::startDrag

02 {

03 QListWidgetItem *item = currentItem;

04 if (item) {

05 QMimeData *mimeData = new QMimeData;

06 mimeData->setText(item->text);

07 QDrag *drag = new QDrag(this);

08 drag->setMimeData(mimeData);

09 drag->setPixmap(QPixmap(":/images/реrson.png"));

10 if (drag->start(Qt::MoveAction) == Qt::MoveAction)

11 delete item;

12 }

13 }

В

функции startDrag мы создаем объект типа QDrag с указанием this в качестве родительского элемента. Объект QDrag хранит данные в объекте QMimeData. В нашем примере мы обеспечиваем данные типа text/plain, используя функцию QMimeData::setText. Класс QMimeData содержит несколько функций, предназначенных для обработки наиболее распространенных типрв объектов переноса (изображений, адресов URL, цветов и т.д.); он может обрабатывать произвольные типы MIME, представленные массивами QByteArray. Вызов QDrag::setPixmap задает пиктограмму, которая следует за курсором в процессе перетаскивания объекта.

Вызов функции QDrag::start запускает операцию перетаскивания объекта и ждет, пока пользователь не отпустит перетаскиваемый объект или не отменит перетаскивание. В аргументе этой функции задается перечень поддерживаемых «операций перетаскивания» (Qt::CopyAction, Qt::MoveAction и Qt::LinkAction); она возвращает ту операцию перетаскивания, которая была выполнена (или Qt::IgnoreAction, если не было выполнено никакой операции). Тип выполняемой операции зависит от того, какие операции допускаются исходным виджетом, какие операции поддерживает целевой виджет и какие клавиши—модификаторы нажаты в момент отпуска переносимого объекта. После вызова этой функции Qt становится владельцем переносимого объекта и удалит его, когда он станет ненужным.

01 void ProjectListWidget::dragEnterEvent(QDragEnterEvent *event)

02 {

03 ProjectListWidget *source =

04 qobject_cast<ProjectListWidget *>(event->source);

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

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

07 event->accept;

08 }

09 }

Виджет ProjectListWidget не только инициирует перенос объектов, он также является местом приема таких объектов, если они приходят от другого виджета ProjectListWidget того же самого приложения. QDragEnterEvent::source возвращает указатель на виджет, который инициирует перенос, если этот виджет принадлежит тому же самому приложению; в противном случае он возвращает нулевой указатель. Мы используем qobject_cast<T>, чтобы убедиться в инициировании переноса виджетом ProjectListWidget. Если все верно, мы указываем Qt на нашу готовность восприятия данного действия как переноса.

01 void ProjectListWidget::dragMoveEvent(QDragMoveEvent *event)

02 {

03 ProjectListWidget *source =

04 qobject_cast<ProjectListWidget *>(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<ProjectListWidget *>(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.

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

До сих пор в представленных примерах мы полагались на поддержку 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). Если данные имеют большой размер, это может излишне замедлять работу приложения. При использовании второго и третьего подходов можно избежать или свести к минимуму эти проблемы. В этом случае мы получаем полное управление и можем использовать эти два подхода совместно.

Поделиться:
Популярные книги

Девочка из прошлого

Тоцка Тала
3. Айдаровы
Любовные романы:
современные любовные романы
5.00
рейтинг книги
Девочка из прошлого

Третий Генерал: Том X

Зот Бакалавр
9. Третий Генерал
Фантастика:
городское фэнтези
аниме
сказочная фантастика
попаданцы
5.00
рейтинг книги
Третий Генерал: Том X

Эволюционер из трущоб. Том 7

Панарин Антон
7. Эволюционер из трущоб
Фантастика:
попаданцы
аниме
фэнтези
фантастика: прочее
5.00
рейтинг книги
Эволюционер из трущоб. Том 7

Я еще граф. Книга #8

Дрейк Сириус
8. Дорогой барон!
Фантастика:
боевая фантастика
попаданцы
5.00
рейтинг книги
Я еще граф. Книга #8

Поводырь

Щепетнов Евгений Владимирович
3. Ботаник
Фантастика:
фэнтези
6.17
рейтинг книги
Поводырь

Законник Российской Империи. Том 2

Ткачев Андрей Юрьевич
2. Словом и делом
Фантастика:
городское фэнтези
альтернативная история
аниме
дорама
6.40
рейтинг книги
Законник Российской Империи. Том 2

Личный аптекарь императора

Карелин Сергей Витальевич
1. Личный аптекарь императора
Фантастика:
городское фэнтези
попаданцы
аниме
фэнтези
5.00
рейтинг книги
Личный аптекарь императора

Государь

Кулаков Алексей Иванович
3. Рюрикова кровь
Фантастика:
мистика
альтернативная история
историческое фэнтези
6.25
рейтинг книги
Государь

Хозяин Стужи

Петров Максим Николаевич
1. Злой Лед
Фантастика:
аниме
фэнтези
попаданцы
7.00
рейтинг книги
Хозяин Стужи

Как прорастают зерна

Волкова Дарья
Любовные романы:
современные любовные романы
7.00
рейтинг книги
Как прорастают зерна

Хозяин Теней 3

Петров Максим Николаевич
3. Безбожник
Фантастика:
попаданцы
аниме
фэнтези
фантастика: прочее
5.00
рейтинг книги
Хозяин Теней 3

Лейтенант. Назад в СССР. Книга 8. Часть 1

Гаусс Максим
8. Второй шанс
Фантастика:
попаданцы
альтернативная история
5.00
рейтинг книги
Лейтенант. Назад в СССР. Книга 8. Часть 1

Наследие Маозари

Панежин Евгений
1. Наследие Маозари
Фантастика:
рпг
попаданцы
аниме
5.80
рейтинг книги
Наследие Маозари

Курс 1. Сентябрь

Фокс Гарри
1. Маркатис
Фантастика:
аниме
фэнтези
сказочная фантастика
5.00
рейтинг книги
Курс 1. Сентябрь