На этом шаге рассмотрим реализацию первой части перетаскивания - drag.
Реализация первой части перетаскивания начинается с перезаписи методов mousePressEvent() и mouseMoveEvent(). В первом из этих методов сохраняется позиция указателя мыши, в которой была нажата кнопка. Эта позиция пригодится в методе mouseMoveEvent() для определения момента старта операции перетаскивания.
Демонстрация метода перетаскивания текстовой информации из окна виджета в окно редактора показана на рис. 1.
Рис.1. Перетаскивание текста
Ниже представлено определение класса Drag:
class Drag : public QLabel { Q_OBJECT private: //атрибут m_ptDragPos предназначен для сохранения положения курсора мыши //в момент нажатия левой кнопки QPoint m_ptDragPos; void startDrag() { //Создается объект класса QMimeData, в который, вызовом метода setText(), //передается перетаскиваемый текст QMimeData* pMimeData = new QMimeData; pMimeData->setText(text()); //Создается объект перетаскивания класса QDrag, в конструктор которого //передается указатель на виджет, из которого осуществляется перетаскивание QDrag* pDrag = new QDrag(this); pDrag->setMimeData(pMimeData); //Вызов метода setPixmap() устанавливает небольшое растровое изображение, //перемещаемое вместе с указателем мыши при перетаскивании pDrag->setPixmap(QPixmap(img1_xpm)); //Метод exec() запускает операцию перетаскивания. //В этот метод можно также передавать значения, влияющие на внешний вид //пиктограммы, находящейся рядом с курсором мыши и поясняющей смысл //действия перетаскивания. Например, для копирования это значение Qt::CopyAction, //для перемещения — Qt::MoveAction, для создания ссылки — Qt::LinkAction. //По умолчанию это значение устанавливается равным Qt::MoveAction. pDrag->exec(Qt::MoveAction); } protected: virtual void mousePressEvent(QMouseEvent* pe) { //если была нажата левая кнопка мыши, //то осуществляется инициализация атрибута m_ptDragPos if (pe->button() == Qt::LeftButton) { m_ptDragPos = pe->pos(); } QWidget::mousePressEvent(pe); } //Метод mouseMoveEvent() нужен для распознавания начала перетаскивания. //Нажатие левой кнопки мыши и последующее перемещение указателя не всегда //говорит о желании пользователя перетащить объект. //Чтобы быть уверенным, необходимо вычислить расстояние между //текущей позицией и той позицией, в которой была нажата левая кнопка мыши. //Если это расстояние превышает величину, возвращаемую статическим //методом startDragDistance() (обычно 4 пиксела), то можно считать, //что перемещение указателя мыши было неслучайным и пользователь //действительно хочет перетащить выбранный объект. virtual void mouseMoveEvent (QMouseEvent* pe) { if (pe->buttons() & Qt::LeftButton) { int distance = (pe->pos() - m_ptDragPos).manhattanLength(); if (distance > QApplication::startDragDistance()) { //вызывается метод startDrag() startDrag(); } } QWidget::mouseMoveEvent(pe); } public: Drag(QWidget* pwgt = 0) : QLabel("Текст для перетаскивания", pwgt) { } };
Файлы приложения можно взять здесь.
На следующем шаге рассмотрим реализацию drop.