Russian Qt Forum

Qt => Пользовательский интерфейс (GUI) => Тема начата: olegkuzn от Январь 21, 2012, 23:49



Название: Drag and Drop в QGraficsView
Отправлено: olegkuzn от Январь 21, 2012, 23:49
Здраствуйте.
Вот код описания и реализации классов участвующих в перетаскивании объектов (текста в данном случае)

//-------------------------------------------------------------------------
// Файл       : DragLabel.h
// назначание : Содержит описание класса DragLabel производного
//              от QLabel, который используется для переноса текста в
//              объект класса DraftView производного от QGraphicsView
//              по технологииDrag and Drop
//-------------------------------------------------------------------------

#ifndef DRAGLABEL_H
#define DRAGLABEL_H
#include <QLabel>

class DragLabel : public QLabel
{
private:
    QPoint m_ptDragPos;

    void StartDrag(void);

protected:

    virtual void mousePressEvent(QMouseEvent *ev);
    virtual void mouseMoveEvent(QMouseEvent *ev);

public:
    DragLabel(QWidget* parent = 0, Qt::WindowFlags f = 0):QLabel(parent, f){}
    DragLabel(const QString& text, QWidget* parent = 0, Qt::WindowFlags f = 0):QLabel(text, parent, f){}
};

#endif // DRAGLABEL_H

//-------------------------------------------------------------------------
// Файл       : DragLabel.cpp
// назначание : Содержит реализацию класса DragLabel производного
//              от QLabel, который используется для переноса текста в
//              объект класса DraftView производного от QGraphicsView
//              по технологииDrag and Drop
//-------------------------------------------------------------------------

#include <QApplication>
#include <QMimeData>
#include <QDrag>
#include <QMouseEvent>
#include "DragLabel.h"
#include "drag.xpm"

void DragLabel::StartDrag(void)
{
   QMimeData* pMimeData = new QMimeData;
   pMimeData->setText(text());
   QDrag* pDrag = new QDrag(this);
   pDrag->setMimeData(pMimeData);
   pDrag->setPixmap(QPixmap(drag_xpm));
   pDrag->exec();
}

/*virtual*/
void DragLabel::mousePressEvent(QMouseEvent *ev)
{
   if(ev->button()== Qt::LeftButton)
       m_ptDragPos = ev->pos();

   QLabel::mousePressEvent(ev);
}

/*virtual*/
void DragLabel::mouseMoveEvent(QMouseEvent *ev)
{
    if(ev->buttons() & Qt::LeftButton)
    {
        int nDistance = (ev->pos() - m_ptDragPos).manhattanLength();
        if(nDistance > QApplication::startDragDistance())
        {
            StartDrag();
        }

    }
    QLabel::mouseMoveEvent(ev);
}

//-------------------------------------------------------------------------
// Файл       : DraftView.h
// назначание : Содержит описание класса DraftView производного от QGraphicsView,
//              который используется для вставки текста из объекта класса DragLabel.
//              Вставка поизводится по технологииDrag and Drop
//-------------------------------------------------------------------------

#ifndef DRAFTVIEW_H
#define DRAFTVIEW_H
#include <QGraphicsView>

class DraftView : public QGraphicsView
{
    Q_OBJECT

public:
    // Конструкторы
    DraftView(QWidget* parent = 0);
    DraftView(QGraphicsScene* scene, QWidget* parent = 0);

protected:

    virtual void dragEnterEvent(QDragEnterEvent*);
    virtual void dropEvent(QDropEvent*);

private:
    QPoint m_ptDrop;
    QString m_strDrop;
};

#endif // DRAFTVIEW_H

//-------------------------------------------------------------------------
// Файл       : DraftView.cpp
// назначание : Содержит реализацию класса DraftView производного от QGraphicsView,
//              который используется для вставки текста из объекта класса DragLabel.
//              Вставка поизводится по технологииDrag and Drop
//-------------------------------------------------------------------------


#include <DraftView.h>
#include <QGraphicsScene>
#include <QMouseEvent>
#include <QMessageBox>

// ----------------------------------------------------------------------
DraftView::DraftView(QWidget* parent /*= 0*/) : QGraphicsView(parent)
{
    setAcceptDrops(true);
    setMouseTracking(true);
}

DraftView::DraftView(QGraphicsScene* scene, QWidget* parent /* = 0*/) : QGraphicsView(scene,parent)
{
    setAcceptDrops(true);
    setMouseTracking(true);
}

// ----------------------------------------------------------------------
/*virtual*/
void DraftView::dragEnterEvent(QDragEnterEvent* pe)
{
    if(pe->mimeData()->hasText())
    {
        pe->acceptProposedAction();  // сюда программа заходит
        //pe->setAccepted(true);
        // pe->accept();
    }

}

// ----------------------------------------------------------------------
/*virtual*/
void DraftView::dropEvent(QDropEvent* pe)
{
    QString str = pe->mimeData()->text();

    m_strDrop = pe->mimeData()->text();
    m_ptDrop = pe->pos();
}

//---------------------------------------------------------------------------//
Если вместо DraftView использовать объект класса производного например от QWidget
то Drag and Drop прекрасно отрабатывает. При DraftView ничего не происходит.
Подскажите в чем проблема. Какие особенности работы c классом QGraphicsView.
Можно ли где-то найти примеры на эту тему.
Заранее благодарен.


Название: Re: Drag and Drop в QGraficsView
Отправлено: yoyo от Февраль 25, 2012, 10:55
Вот что по этому поводу говорит справка Qt:
Цитировать
QGraphicsView inherits the drag and drop functionality provided by QWidget. When it receives a drag and drop event, it translates it to a QGraphicsSceneDragDropEvent.
Т.е., необходимо, чтобы не QGraphicsView, а объект сцены обрабатывал dragEnterEvent и dropEvent. Есть хороший пример в Qt, - dragdroprobot.