Главная · Все классы · Основные классы · Классы по группам · Модули · Функции

Пример "Draggable Icons"

Файлы:

Пример "Draggable Icons" показывает, как перетаскивать изображение между виджетами в одном и том же приложении, а также между разными приложениями.

Во многих ситуациях, где используется перетаскивание, the пользователь начинает перетаскивание из одного виджета и отпускает полезную нагрузку на другой виджет. В данном примере мы создаем подкласс QLabel чтобы создать метки, которые мы используем в качестве источников перетаскивания, и помещаем их внутри объектов QWidget, которые выступают и как контейнеры, и как точки отпускания.

Кроме того, когда происходит операция перетаскивания, мы желаем отправить больше чем только изображение. Мы также хотим отправить информацию о том, где пользователь щелкнул в изображении для того, чтобы пользователь мог поместить его точно над целью отпускания. Эта степень детализации означает, что мы должны создать пользовательский MIME-тип для наших данных.

Определение класса DragWidget

Виджеты пиктограмм, которые мы используем для вывода на экран пиктограмм, являются наследниками QLabel:

 class DragWidget : public QFrame
 {
 public:
     DragWidget(QWidget *parent=0);

 protected:
     void dragEnterEvent(QDragEnterEvent *event);
     void dragMoveEvent(QDragMoveEvent *event);
     void dropEvent(QDropEvent *event);
     void mousePressEvent(QMouseEvent *event);
 };

Поскольку класс QLabel предоставляет большинство из того, что мы требовали для пиктограммы, нам нужно только повторно реализовать QWidget::mousePressEvent() чтобы предоставить возможности перетаскивания.

Реализация класса DragWidget

Конструктор DragWidget устанавливает атрибут виджета, гарантирующий что виджет будет уничтожен когда его закроют:

 DragWidget::DragWidget(QWidget *parent)
     : QFrame(parent)
 {
     setMinimumSize(200, 200);
     setFrameStyle(QFrame::Sunken | QFrame::StyledPanel);
     setAcceptDrops(true);

     QLabel *boatIcon = new QLabel(this);
     boatIcon->setPixmap(QPixmap(":/images/boat.png"));
     boatIcon->move(20, 20);
     boatIcon->show();
     boatIcon->setAttribute(Qt::WA_DeleteOnClose);

     QLabel *carIcon = new QLabel(this);
     carIcon->setPixmap(QPixmap(":/images/car.png"));
     carIcon->move(120, 20);
     carIcon->show();
     carIcon->setAttribute(Qt::WA_DeleteOnClose);

     QLabel *houseIcon = new QLabel(this);
     houseIcon->setPixmap(QPixmap(":/images/house.png"));
     houseIcon->move(20, 120);
     houseIcon->show();
     houseIcon->setAttribute(Qt::WA_DeleteOnClose);
 }

Что разрешить перетаскивание из пиктограммы, нам нужно действовать при событии нажатия кнопки мыши. Мы делаем это повторно реализовав QWidget::mousePressEvent() и установив объект QDrag.

 void DragWidget::mousePressEvent(QMouseEvent *event)
 {
     QLabel *child = static_cast<QLabel*>(childAt(event->pos()));
     if (!child)
         return;

     QPixmap pixmap = *child->pixmap();

     QByteArray itemData;
     QDataStream dataStream(&itemData, QIODevice::WriteOnly);
     dataStream << pixmap << QPoint(event->pos() - child->pos());

Поскольку мы будем отправлять данные растрового изображения для пиктограммы и информацию о щелчке пользователя в виджете пиктограммы, мы создаём QByteArray и упаковываем детали используя QDataStream.

Для совместимости операции перетаскивания описывают данные, которые они содержат, используя MIME-типы. В Qt, мы описываем эти данные используя объект QMimeData:

     QMimeData *mimeData = new QMimeData;
     mimeData->setData("application/x-dnditemdata", itemData);

Мы выбрали неофициальный MIME-тип для этой цели и предоставили QByteArray для объекта данных MIME.

Сама операция перетаскивания обрабатывается объектом QDrag:

     QDrag *drag = new QDrag(this);
     drag->setMimeData(mimeData);
     drag->setPixmap(pixmap);
     drag->setHotSpot(event->pos() - child->pos());

Здесь мы передаём данные в объект перетаскивания, устанавливаем растровое изображение, которое будет показано около курсора во время выполнения операции, и определяем позицию активной точки, в которую помещают позицию растрового изображения под курсором.


Copyright © 2008 Trolltech Торговые марки
Qt 4.3.5