Suppose I want my draggable widget to move differently than just staying under my cursor while being dragged. For instance, having the widget move only in one axis, or have the widget move double the distance between the cursor and the drag starting point. Which method should I override to define this kind of behaviour?
For a widget these four methods control the behaviour of a dragged widget :
virtual void dragEnterEvent ( QDragEnterEvent * event )
virtual void dragLeaveEvent ( QDragLeaveEvent * event )
virtual void dragMoveEvent ( QDragMoveEvent * event )
virtual void dropEvent ( QDropEvent * event )
I guess you have to reimplement the dragMoveEvent
to achieve what you want.
I think you should ask yourself a question: do you have some draggable elements I want to drag to specific targets (for example you have widgets that represent pieces of different shapes that should be dragged on other widgets representing holes and each "hole" accepts only pieces of the same shape) or do you just want to move one widget over the other widget?
If you need drag & drop functionality, it seems to me that you can't really change the behavior during mouse moving - it's more or less hardcoded into QDrag object.
If you just want to move stuff around, you should be able to do it only be reimplementing mouse Move/Press/Release events (you might also need to enable mouse tracking by QWidget::setMouseTracking method).
EDIT:
This is sample code for draggable label for "just moving stuff around":
#ifndef DRAGGABLELABEL_H
#define DRAGGABLELABEL_H
#include <QLabel>
#include <QPoint>
#include <QMouseEvent>
class DraggableLabel : public QLabel
{
Q_OBJECT
public:
explicit DraggableLabel(const QString &text, QWidget *parent = 0) : QLabel(text, parent) {}
protected:
void mousePressEvent(QMouseEvent *event) {
dragStart = event->pos();
}
void mouseMoveEvent(QMouseEvent *event) {
setGeometry(QRect(geometry().topLeft() + event->pos() - dragStart, rect().size()));
}
private:
QPoint dragStart;
};
#endif // DRAGGABLELABEL_H
Now you just need to add it to your main widget:
#include <QApplication>
#include <QWidget>
#include "draggablelabel.h"
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
QWidget mainWindow;
DraggableLabel *label = new DraggableLabel("Test", &mainWindow);
mainWindow.setMinimumSize(200, 200);
mainWindow.show();
return a.exec();
}
You can experiment with moveMouseEvent to achieve dragging only in one axis.