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. dragEnterEvent from external file issue

dragEnterEvent from external file issue

Scheduled Pinned Locked Moved Unsolved General and Desktop
11 Posts 2 Posters 3.2k 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.
  • UnitScanU Offline
    UnitScanU Offline
    UnitScan
    wrote on last edited by UnitScan
    #1

    I have a situation like this: http://imgur.com/a/4BpNv
    I have a sublclass derived from QTableWidget, modified to accept drag'n drop both internal row and external file. When I drag a file from a Window folder to the TableWidget, the dnd animation stop ath the edge of the TableWidget, preventing me to freely move the mouse inside the TableWidget to select the point where I run the drop. This only happens when I drag file directly from Windows folders, while if I drag files from the Qt API QFileDialog::getOpenFileName() dialog the the dnd works as I would like.

    This is the subclass:

    #include <QtGui>
    #include <QDrag>
    #include <QPainter>
    #include <QDropEvent>
    #include <QCursor>
    #include "dtablewidget.h"
    
    DTableWidget::DTableWidget(QWidget *parent) : QTableWidget(parent) {
        //set widget default properties:
    
        viewport()->setAcceptDrops(true); //set accept drop on viewport
        setDragEnabled(true);
        setDragDropOverwriteMode(false); //set drag drop overwrite to false
        setDragDropMode(QAbstractItemView::DragDrop); //enable internal drag drop on tablular dispaly
        setSelectionBehavior(QAbstractItemView::SelectRows); //enable selection of entire row
        setEditTriggers(QAbstractItemView::NoEditTriggers);//preventing editing
        setAlternatingRowColors(true);
        setSelectionBehavior(QAbstractItemView::SelectRows);
        setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOn);
        setShowGrid(false);
        setAcceptDrops(true);
        setWordWrap(false);
        setStyleSheet("selection-background-color: yellow;"
                      "selection-color: #002041;"
                      "font-size: 75%;"
                      );
    
    }
    
    void DTableWidget::dragEnterEvent(QDragEnterEvent *event) {
        qDebug() << "dragEnterEvent";
        event->accept();
    }
    
    void DTableWidget::dragMoveEvent(QDragMoveEvent *event) {
        qDebug() << "dragMoveEvent";
        if (event->source() != this) {
            QDrag *drag = new QDrag(this);
            QMimeData *mimeData = new QMimeData;
            mimeData->setUrls(event->mimeData()->urls());
            drag->setMimeData(mimeData);
            drag->exec(Qt::LinkAction);
    }
        else {
            event->acceptProposedAction();
            event->setDropAction(Qt::LinkAction);
        }
    }
    
    void DTableWidget::dropEvent(QDropEvent *event) {
        event->acceptProposedAction();
        event->setDropAction(Qt::LinkAction);
        qDebug() << "dropEvent" << event << event->mimeData()->urls().count();
        if (event->mimeData()->urls().count() > 0) {
            emit dropped(event->mimeData());
            qDebug() << "dropEvent" << event->mimeData()->urls().count();
        }
        else {
            QPoint old_coordinates = QPoint(-1,-1);
            if(currentItem() != NULL) //Check if user is not accessing empty cell
            {
                old_coordinates = QPoint(currentItem()->row(), currentItem()->column());
            }
            if(this->itemAt(event->pos().x(), event->pos().y()) != NULL && old_coordinates != QPoint(-1, -1))
            {
                emit moved(old_coordinates.x(), itemAt( event->pos().x(), event->pos().y())->row());
            }
        }
    }
    
    void DTableWidget::dragLeaveEvent(QDragLeaveEvent *event) {
        qDebug() << "dragLeaveEvent";
    }
    
    void DTableWidget::keyPressEvent(QKeyEvent *event) {
        emit keyboard(event);
    }
    
    void DTableWidget::startDrag(Qt::DropActions supportedActions) {
        QModelIndexList indexes = selectedIndexes();
        if (indexes.count() > 0) {
            QMimeData *data = model()->mimeData(indexes);
            if (!data)
                return;
            QDrag *drag = new QDrag(this);
            drag->setMimeData(data);
            Qt::DropAction defaultDropAction = Qt::IgnoreAction;
            if (defaultDropAction != Qt::IgnoreAction && (supportedActions & defaultDropAction))
                defaultDropAction = defaultDropAction;
            else if (supportedActions & Qt::CopyAction && dragDropMode() != QAbstractItemView::InternalMove)
                defaultDropAction = Qt::MoveAction;
            drag->exec(defaultDropAction);
        }
    }
    
    

    Can you help me?

    raven-worxR 1 Reply Last reply
    0
    • UnitScanU UnitScan

      I have a situation like this: http://imgur.com/a/4BpNv
      I have a sublclass derived from QTableWidget, modified to accept drag'n drop both internal row and external file. When I drag a file from a Window folder to the TableWidget, the dnd animation stop ath the edge of the TableWidget, preventing me to freely move the mouse inside the TableWidget to select the point where I run the drop. This only happens when I drag file directly from Windows folders, while if I drag files from the Qt API QFileDialog::getOpenFileName() dialog the the dnd works as I would like.

      This is the subclass:

      #include <QtGui>
      #include <QDrag>
      #include <QPainter>
      #include <QDropEvent>
      #include <QCursor>
      #include "dtablewidget.h"
      
      DTableWidget::DTableWidget(QWidget *parent) : QTableWidget(parent) {
          //set widget default properties:
      
          viewport()->setAcceptDrops(true); //set accept drop on viewport
          setDragEnabled(true);
          setDragDropOverwriteMode(false); //set drag drop overwrite to false
          setDragDropMode(QAbstractItemView::DragDrop); //enable internal drag drop on tablular dispaly
          setSelectionBehavior(QAbstractItemView::SelectRows); //enable selection of entire row
          setEditTriggers(QAbstractItemView::NoEditTriggers);//preventing editing
          setAlternatingRowColors(true);
          setSelectionBehavior(QAbstractItemView::SelectRows);
          setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOn);
          setShowGrid(false);
          setAcceptDrops(true);
          setWordWrap(false);
          setStyleSheet("selection-background-color: yellow;"
                        "selection-color: #002041;"
                        "font-size: 75%;"
                        );
      
      }
      
      void DTableWidget::dragEnterEvent(QDragEnterEvent *event) {
          qDebug() << "dragEnterEvent";
          event->accept();
      }
      
      void DTableWidget::dragMoveEvent(QDragMoveEvent *event) {
          qDebug() << "dragMoveEvent";
          if (event->source() != this) {
              QDrag *drag = new QDrag(this);
              QMimeData *mimeData = new QMimeData;
              mimeData->setUrls(event->mimeData()->urls());
              drag->setMimeData(mimeData);
              drag->exec(Qt::LinkAction);
      }
          else {
              event->acceptProposedAction();
              event->setDropAction(Qt::LinkAction);
          }
      }
      
      void DTableWidget::dropEvent(QDropEvent *event) {
          event->acceptProposedAction();
          event->setDropAction(Qt::LinkAction);
          qDebug() << "dropEvent" << event << event->mimeData()->urls().count();
          if (event->mimeData()->urls().count() > 0) {
              emit dropped(event->mimeData());
              qDebug() << "dropEvent" << event->mimeData()->urls().count();
          }
          else {
              QPoint old_coordinates = QPoint(-1,-1);
              if(currentItem() != NULL) //Check if user is not accessing empty cell
              {
                  old_coordinates = QPoint(currentItem()->row(), currentItem()->column());
              }
              if(this->itemAt(event->pos().x(), event->pos().y()) != NULL && old_coordinates != QPoint(-1, -1))
              {
                  emit moved(old_coordinates.x(), itemAt( event->pos().x(), event->pos().y())->row());
              }
          }
      }
      
      void DTableWidget::dragLeaveEvent(QDragLeaveEvent *event) {
          qDebug() << "dragLeaveEvent";
      }
      
      void DTableWidget::keyPressEvent(QKeyEvent *event) {
          emit keyboard(event);
      }
      
      void DTableWidget::startDrag(Qt::DropActions supportedActions) {
          QModelIndexList indexes = selectedIndexes();
          if (indexes.count() > 0) {
              QMimeData *data = model()->mimeData(indexes);
              if (!data)
                  return;
              QDrag *drag = new QDrag(this);
              drag->setMimeData(data);
              Qt::DropAction defaultDropAction = Qt::IgnoreAction;
              if (defaultDropAction != Qt::IgnoreAction && (supportedActions & defaultDropAction))
                  defaultDropAction = defaultDropAction;
              else if (supportedActions & Qt::CopyAction && dragDropMode() != QAbstractItemView::InternalMove)
                  defaultDropAction = Qt::MoveAction;
              drag->exec(defaultDropAction);
          }
      }
      
      

      Can you help me?

      raven-worxR Offline
      raven-worxR Offline
      raven-worx
      Moderators
      wrote on last edited by
      #2

      @UnitScan said in dragEnterEvent from external file issue:

      void DTableWidget::dragMoveEvent

      i stopped reading after i saw your implementation of the dragMoveEvent() becasue its so horribly wrong :)

      Why do you create a new QDrag there?
      When you receive a dragMoveEvent it means that there is already a drag currently happening, otherwise you wouldn't receive the event in the first place.

      Just remove the whole if (event->source() != this) block and it should work.
      If you really have to check if the drag origins from inside your application do event->source(). If it returns a null-pointer the drag comes from outside your application.

      --- SUPPORT REQUESTS VIA CHAT WILL BE IGNORED ---
      If you have a question please use the forum so others can benefit from the solution in the future

      1 Reply Last reply
      0
      • UnitScanU Offline
        UnitScanU Offline
        UnitScan
        wrote on last edited by
        #3

        I created a new QDrag because I wish to change the horrible mouse cursor pixmap that appears during dragMoveEvent, and replace it with a simple Leftarrow, without the preview of the file I'm dragging, with the small symbol of the link at the bottom right of the cursor.

        void DTableWidget::dragMoveEvent(QDragMoveEvent *event) {
        
            qDebug() << "dragMoveEvent";
            if (event->source() != this) {
                QDrag *drag = new QDrag(this);
                QCursor cursor;
                cursor.setShape(Qt::ArrowCursor);
        
                drag->setPixmap(cursor.pixmap());
                this->cursor().setShape(Qt::ArrowCursor);
                drag->setDragCursor(this->cursor().pixmap(),Qt::LinkAction);
                QMimeData *mimeData = new QMimeData;
                mimeData->setUrls(event->mimeData()->urls());
                drag->setMimeData(mimeData);
                drag->exec(Qt::LinkAction);
        }
            else {
        
                event->acceptProposedAction();
                event->setDropAction(Qt::LinkAction);
            }
        }
        

        If there is a better way to do that, what is?

        raven-worxR 1 Reply Last reply
        0
        • UnitScanU UnitScan

          I created a new QDrag because I wish to change the horrible mouse cursor pixmap that appears during dragMoveEvent, and replace it with a simple Leftarrow, without the preview of the file I'm dragging, with the small symbol of the link at the bottom right of the cursor.

          void DTableWidget::dragMoveEvent(QDragMoveEvent *event) {
          
              qDebug() << "dragMoveEvent";
              if (event->source() != this) {
                  QDrag *drag = new QDrag(this);
                  QCursor cursor;
                  cursor.setShape(Qt::ArrowCursor);
          
                  drag->setPixmap(cursor.pixmap());
                  this->cursor().setShape(Qt::ArrowCursor);
                  drag->setDragCursor(this->cursor().pixmap(),Qt::LinkAction);
                  QMimeData *mimeData = new QMimeData;
                  mimeData->setUrls(event->mimeData()->urls());
                  drag->setMimeData(mimeData);
                  drag->exec(Qt::LinkAction);
          }
              else {
          
                  event->acceptProposedAction();
                  event->setDropAction(Qt::LinkAction);
              }
          }
          

          If there is a better way to do that, what is?

          raven-worxR Offline
          raven-worxR Offline
          raven-worx
          Moderators
          wrote on last edited by
          #4

          @UnitScan said in dragEnterEvent from external file issue:

          event->setDropAction(Qt::LinkAction);

          you mean like you do in the else-block afterwards?
          Basically it's only possible to set the cursor during a drag to 4 states:
          Copy, Move, Link, NoAction. The operating system decides how to show them.

          Thus setting it to a "plain" cursor isn't possible.

          --- SUPPORT REQUESTS VIA CHAT WILL BE IGNORED ---
          If you have a question please use the forum so others can benefit from the solution in the future

          raven-worxR 1 Reply Last reply
          0
          • UnitScanU Offline
            UnitScanU Offline
            UnitScan
            wrote on last edited by
            #5

            I don't want a plain cursor, but a dragCursor(Qt::LinkAction). How can I do it?

            1 Reply Last reply
            0
            • raven-worxR raven-worx

              @UnitScan said in dragEnterEvent from external file issue:

              event->setDropAction(Qt::LinkAction);

              you mean like you do in the else-block afterwards?
              Basically it's only possible to set the cursor during a drag to 4 states:
              Copy, Move, Link, NoAction. The operating system decides how to show them.

              Thus setting it to a "plain" cursor isn't possible.

              raven-worxR Offline
              raven-worxR Offline
              raven-worx
              Moderators
              wrote on last edited by raven-worx
              #6

              you are already doing it in the else-block (event->setDropAction()) like i already said in my previous post!
              The "drag image" cannot be removed. Not via Qt API at least.

              --- SUPPORT REQUESTS VIA CHAT WILL BE IGNORED ---
              If you have a question please use the forum so others can benefit from the solution in the future

              1 Reply Last reply
              0
              • UnitScanU Offline
                UnitScanU Offline
                UnitScan
                wrote on last edited by UnitScan
                #7

                I noticed that with Clementine, player made with QT5 libraries, when you drag an external file to the playlist appears only a LeftArrorw with a small square at the bottom right with the "+" symbol, while with me appears, beyond Leftarrow, a gigantic preview of the file I'm dragging and an abnormal word "Link" at the bottom right :'-(
                Changing event->setDropAction(Qt::LinkAction) to event->setDropAction(Qt::CopyAction) replace only the abnormal text label from "Link" to "Copy"

                raven-worxR 1 Reply Last reply
                0
                • UnitScanU UnitScan

                  I noticed that with Clementine, player made with QT5 libraries, when you drag an external file to the playlist appears only a LeftArrorw with a small square at the bottom right with the "+" symbol, while with me appears, beyond Leftarrow, a gigantic preview of the file I'm dragging and an abnormal word "Link" at the bottom right :'-(
                  Changing event->setDropAction(Qt::LinkAction) to event->setDropAction(Qt::CopyAction) replace only the abnormal text label from "Link" to "Copy"

                  raven-worxR Offline
                  raven-worxR Offline
                  raven-worx
                  Moderators
                  wrote on last edited by
                  #8

                  @UnitScan
                  And you are sure they just use the Qt API for Drag-n-Drop handling?!
                  Anyway you can check the source code how they do it.

                  --- SUPPORT REQUESTS VIA CHAT WILL BE IGNORED ---
                  If you have a question please use the forum so others can benefit from the solution in the future

                  1 Reply Last reply
                  0
                  • UnitScanU Offline
                    UnitScanU Offline
                    UnitScan
                    wrote on last edited by
                    #9

                    There are other way out of Qt to handle drag'n drop?

                    raven-worxR 1 Reply Last reply
                    0
                    • UnitScanU UnitScan

                      There are other way out of Qt to handle drag'n drop?

                      raven-worxR Offline
                      raven-worxR Offline
                      raven-worx
                      Moderators
                      wrote on last edited by raven-worx
                      #10

                      @UnitScan
                      using the native API directly for example

                      But again to make sure: On the same machine (same OS) the Clementine player doesn't show the drag image while your application does?

                      --- SUPPORT REQUESTS VIA CHAT WILL BE IGNORED ---
                      If you have a question please use the forum so others can benefit from the solution in the future

                      1 Reply Last reply
                      0
                      • UnitScanU Offline
                        UnitScanU Offline
                        UnitScan
                        wrote on last edited by UnitScan
                        #11

                        @raven-worx Yes. on Windows Clementine shows only the small "+" on the bottom right, while my app show the gigantic file preview and the "Link" text

                        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