Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. QGraphicsWidget and drag&drop

QGraphicsWidget and drag&drop

Scheduled Pinned Locked Moved General and Desktop
3 Posts 2 Posters 1.6k Views
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • L Offline
    L Offline
    Lipwig
    wrote on last edited by
    #1

    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?

    1 Reply Last reply
    0
    • L Offline
      L Offline
      Lipwig
      wrote on last edited by
      #2

      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());
      }
      

      };@

      1 Reply Last reply
      0
      • SGaistS Offline
        SGaistS Offline
        SGaist
        Lifetime Qt Champion
        wrote on last edited by
        #3

        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

        Interested in AI ? www.idiap.ch
        Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

        1 Reply Last reply
        0

        • Login

        • Login or register to search.
        • First post
          Last post
        0
        • Categories
        • Recent
        • Tags
        • Popular
        • Users
        • Groups
        • Search
        • Get Qt Extensions
        • Unsolved