Шаг 122.
Библиотека Qt.
Реализация drag

    На этом шаге рассмотрим реализацию первой части перетаскивания - 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.




Предыдущий шаг Содержание Следующий шаг