Я пытаюсь сделать простой перетаскиваемый элемент, используя графический фреймворк. Вот код для того, что я сделал до сих пор:
Класс виджетов:
class Widget : public QWidget
{
Q_OBJECT
public:
Widget(QWidget *parent = 0);
~Widget();
};
Widget::Widget(QWidget *parent)
: QWidget(parent)
{
DragScene *scene = new DragScene();
DragView *view = new DragView();
QHBoxLayout *layout = new QHBoxLayout();
DragItem *item = new DragItem();
view->setAcceptDrops(true);
scene->addItem(item);
view->setScene(scene);
layout->addWidget(view);
this->setLayout(layout);
}
Widget::~Widget()
{
}
Класс DragView:
class DragView : public QGraphicsView
{
public:
DragView(QWidget *parent = 0);
};
DragView::DragView(QWidget *parent) : QGraphicsView(parent)
{
setRenderHints(QPainter::Antialiasing);
}
Класс DragScene:
class DragScene : public QGraphicsScene
{
public:
DragScene(QObject* parent = 0);
protected:
void dragEnterEvent(QGraphicsSceneDragDropEvent *event);
void dragMoveEvent(QGraphicsSceneDragDropEvent *event);
void dragLeaveEvent(QGraphicsSceneDragDropEvent *event);
void dropEvent(QGraphicsSceneDragDropEvent *event);
};
DragScene::DragScene(QObject* parent) : QGraphicsScene(parent)
{
}
void DragScene::dragEnterEvent(QGraphicsSceneDragDropEvent *event){
}
void DragScene::dragMoveEvent(QGraphicsSceneDragDropEvent *event){
}
void DragScene::dragLeaveEvent(QGraphicsSceneDragDropEvent *event){
}
void DragScene::dropEvent(QGraphicsSceneDragDropEvent *event){
qDebug() << event->pos();
event->acceptProposedAction();
DragItem *item = new DragItem();
this->addItem(item);
// item->setPos(event->pos()); before badgerr's tip
item->setPos(event->scenePos());
}
Класс DragItem:
class DragItem : public QGraphicsItem
{
public:
DragItem(QGraphicsItem *parent = 0);
QRectF boundingRect() const;
void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget = 0);
protected:
void mouseDoubleClickEvent(QGraphicsSceneMouseEvent *event);
void mouseMoveEvent(QGraphicsSceneMouseEvent *event);
void mousePressEvent(QGraphicsSceneMouseEvent *event);
void mouseReleaseEvent(QGraphicsSceneMouseEvent *event);
};
DragItem::DragItem(QGraphicsItem *parent) : QGraphicsItem(parent)
{
setFlag(QGraphicsItem::ItemIsMovable);
}
QRectF DragItem::boundingRect() const{
const QPointF *p0 = new QPointF(-10,-10);
const QPointF *p1 = new QPointF(10,10);
return QRectF(*p0,*p1);
}
void DragItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget){
if(painter == 0)
painter = new QPainter();
painter->drawEllipse(QPoint(0,0),10,10);
}
void DragItem::mouseDoubleClickEvent(QGraphicsSceneMouseEvent *event){
}
void DragItem::mouseMoveEvent(QGraphicsSceneMouseEvent *event){
}
void DragItem::mousePressEvent(QGraphicsSceneMouseEvent *event){
QMimeData* mime = new QMimeData();
QDrag* drag = new QDrag(event->widget());
drag->setMimeData(mime);
drag->exec();
}
void DragItem::mouseReleaseEvent(QGraphicsSceneMouseEvent *event){
}
main.cpp создает экземпляр виджета и показывает его. Когда я пытаюсь перетащить круг, приложение просто создает еще один круг поверх исходного, независимо от того, где я отпущу перетаскивание. qDebug () в dropEvent () DragScene показывает QPointF (0,0) каждый раз, когда заканчивается перетаскивание. Я с трудом пытаюсь понять, что именно я должен делать, какие классы я должен подклассить, какие методы нужно переопределить, чтобы эта работа работала. Документация не очень подробна. Я хотел бы знать, как заставить это работать, и если есть какой-то другой, более полный ресурс, чтобы узнать о платформе графического представления, кроме официальной документации (которая, между прочим, отлично, но было бы здорово, если бы была более подробная трактат на эту тему).
EDIT:
Следуя совету барсука, я заменил item-> pos () в DragScene :: dropEvent () на item-> scenePos (), теперь событие drop создает новый круг на сайте перетаскивания, который более или менее соответствует в розыске. Но исходный круг все еще находится на месте, и пока идет перетаскивание, элемент не следует за курсором мыши.
В документации QGraphicsSceneDragDropEvent говорится, что pos () должна возвращать позицию курсора относительно представления, отправляющего событие, которое, если я не ошибаюсь, не должно быть (0,0) все время. Weird.
Я прочитал в сообщении на форуме, что вы можете использовать QDrag :: setPixMap (), чтобы показать что-то во время перетаскивания, и в примерах я видел изображения, которые устанавливаются как растровые изображения, но как я могу сделать растровое изображение таким же, как графический элемент, который я должен перетаскивать?