Пример "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());
Здесь мы передаём данные в объект перетаскивания, устанавливаем растровое изображение, которое будет показано около курсора во время выполнения операции, и определяем позицию активной точки, в которую помещают позицию растрового изображения под курсором.
Авторские права © 2010 Nokia Corporation и/или её дочерние компании |
Торговые марки |
Qt 4.6.4 |
|