QGraphicsWidget and drag&drop
-
Hello! I created a very simple test application to test the drag & drop mechanism in a graphics scene.
@MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);//setup scene and view QGraphicsView *view = new QGraphicsView(ui->centralWidget); QGraphicsScene *scene = new QGraphicsScene(0, 0, 2000, 2000, view); scene->setSceneRect(-100,-100,400,400); view->setTransformationAnchor(QGraphicsView::NoAnchor); view->setScene(scene); //create textedit, should be able to accept drag & drop QTextEdit *edit = new QTextEdit(0); edit->setAcceptDrops(true); QGraphicsProxyWidget *proxy = scene->addWidget(edit); proxy->setGeometry( QRectF( 0,0,100,60)); proxy->setAcceptDrops(true); //just create an additional button as another widget which should be able to accept drag & drop, too QPushButton *btn = new QPushButton(0); btn->setAcceptDrops(true); QGraphicsProxyWidget *proxy2 = scene->addWidget(btn); proxy2->setGeometry( QRectF( 0,110,60,25)); proxy2->setAcceptDrops(true); //this circle can be draged to another item MyEllipse *ell = new MyEllipse(); ell->setRect(QRectF(120,30,20,20) ); scene->addItem(ell); ell->installSceneEventFilter(ell); //another circle which can receive drops as intended QGraphicsEllipseItem *ell2 = new QGraphicsEllipseItem(); ell2->setRect(QRectF(120,70,20,20) ); ell2->setAcceptDrops(true); scene->addItem(ell2);
}@
We have a QTextEdit and a QPushButton on the scene. An ellipse (MyEllipse *ell) which will act a source for the drag&drop and a second ellipse (ell2) as an additional drop destination. Source for MyEllipse:
@MyEllipse::MyEllipse()
{}
bool MyEllipse::sceneEventFilter(QGraphicsItem watched, QEvent event)
{
if( event->type() == QEvent::GraphicsSceneMousePress)
{
QGraphicsSceneMouseEvent e = dynamic_cast<QGraphicsSceneMouseEvent>(event);
qDebug() << " yes, drag";
QMimeData mime = new QMimeData();
QDrag drag = new QDrag((QObject*)e->widget());
drag->setMimeData(mime);
drag->exec();
}
}@The problem: ell2 will accept the drop event as intended - the mouse cursor changes, the handling of the drop event is missing in my example. But in case of edit and btn the cursor does not change, therefore, the drop event will be ignored. But why, or better: how to fix this problem?
-
OK, I recently found the solution ("QtFAQ":http://qt-project.org/faq/answer/how_can_i_do_drag_and_drop_in_a_widget), you definitely have to override dragEnterEvent and dragMoveEvent and "manually" accept the event. I do not know why this is necessary even though setAcceptDrops is set true. Is this a design mistake in the Qt framework or is there any good reason why it is realized this way?
Here is the solution to make the Button able to receive and handle a drop event:
@class MyButton : public QPushButton
{
public:
MyButton();virtual void dragEnterEvent(QDragEnterEvent *event) { event->acceptProposedAction(); } virtual void dragMoveEvent(QDragMoveEvent *de) { de->accept(); } virtual void dropEvent(QDropEvent *de) { qDebug() << "dropped ..."; qDebug("Contents: %s", de->mimeData()->text().toLatin1().data()); }
};@
-
Hi and welcome to devnt,
setAcceptDrops means that you would like your item to be able to react to drag and drop events. However, it's up to you tell when it it's actually time to accept something. e.g. you could have a text rendering item that should only accept drops when the content of the mime data has text in it and not the rest of the time. Or if you take a word processing application it won't accept e.g. PDF but will for plain text file.
Hope it helps