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. Disable auto remove row in drag drop
QtWS25 Last Chance

Disable auto remove row in drag drop

Scheduled Pinned Locked Moved Unsolved General and Desktop
10 Posts 3 Posters 4.7k 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.
  • S Offline
    S Offline
    samdol
    wrote on last edited by samdol
    #1

    Hi,

    I made a drag and drop support for TreeView/ListView according to
    http://doc.qt.io/qt-4.8/model-view-programming.html
    I did not included the part

    insertRows(beginRow, rows, QModelIndex());
    foreach (const QString &text, newItems) {
        QModelIndex idx = index(beginRow, 0, QModelIndex());
        setData(idx, text);
        beginRow++;
    }
    

    because I did it manually in mainWindow. When I drag by Qt::CopyAction, I have no problem.
    The problem is that when I move an item from ListView to TreeView by Qt::MoveAction, it seems it automatically removes a row in QListView.
    It may make sence. But I would like to do it manually in mainWindow. How can I disable this removing row automatically function when I use Qt::MoveAction?

    And When I drag files by Qt::CopyAction, it shows "+" mouse cursor shape and by Qt::MoveAction, it shows "->" mouse cursor shape. How can I change these shape to other shapes?

    1 Reply Last reply
    0
    • joeQJ Offline
      joeQJ Offline
      joeQ
      wrote on last edited by
      #2

      @samdol Hi, friend, welcome.

      Maybe you can try the Qt::CopyAction. Try again.

      Qt manual:

      Qt::CopyAction Copy the data to the target.
      Qt::MoveAction Move the data from the source to the target.

      Just do it!

      S 1 Reply Last reply
      0
      • joeQJ joeQ

        @samdol Hi, friend, welcome.

        Maybe you can try the Qt::CopyAction. Try again.

        Qt manual:

        Qt::CopyAction Copy the data to the target.
        Qt::MoveAction Move the data from the source to the target.

        S Offline
        S Offline
        samdol
        wrote on last edited by
        #3

        @joeQ
        Thanks, but I need both actions.

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

          Hi,

          If you want to change the original behaviour then you have to re-implement the drag and drop feature to match what you want to do.

          Out of curiosity, why do you want that modified behaviour ?

          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
          • S samdol

            @joeQ
            Thanks, but I need both actions.

            joeQJ Offline
            joeQJ Offline
            joeQ
            wrote on last edited by
            #5

            @samdol oh, maybe you should reimplement the drag and drop event. like following code.

            void ListWidget::dragEnterEvent(QDragEnterEvent *event)
            {
                if (event->mimeData()->hasFormat("image/list-item"))
                    event->accept();
                else
                    event->ignore();
            }
            
            void ListWidget::dragMoveEvent(QDragMoveEvent *event)
            {
                if (event->mimeData()->hasFormat("image/list-item")) {
                    event->setDropAction(Qt::MoveAction);
                    event->accept();
                } else {
                    event->ignore();
                }
            }
            
            void ListWidget::dropEvent(QDropEvent *event)
            {
                QListWidgetItem *pItem = NULL;
                QListWidgetItem *pPosItem = NULL;
                if (event->mimeData()->hasFormat("image/list-item"))
                {
                    if( NULL == m_pDragItem )
                    {
                        event->ignore();
                        return;
                    }
                    pPosItem = itemAt( event->pos() );
                    if( NULL == pPosItem )
                    {
                        event->ignore();
                        return;
                    }
            
                    pItem = m_pDragItem->clone();
                    insertItem(row(pPosItem), pItem); ///< insert item
                    event->setDropAction(Qt::MoveAction);
                    m_pDragItem = NULL;
                    event->accept();
                }
            
            }
            
            void ListWidget::startDrag(Qt::DropActions supportedActions)
            {
                Q_UNUSED( supportedActions );
            
                QDrag *pDrag = NULL;
                QByteArray itemData;
                QMimeData *pMimeData = NULL;
                QListWidgetItem *pItem = currentItem();
                if( NULL == pItem ){return;}
                if( NULL != m_pDragItem ){return;}
                if( count() <= 1 ){return;}
                clearSelection();
            
                pMimeData = new QMimeData;
                pMimeData->setData("image/list-item", itemData);
            
                pDrag = new QDrag(this);
                pDrag->setMimeData(pMimeData);
            
                m_bDraging = true;
                m_pDragItem = pItem;
                if (pDrag->exec(Qt::MoveAction) == Qt::MoveAction)
                {
                     /** after the drag and not to delete the item */
                    //delete takeItem(row(pItem)); ///< remove the item
                }
            
            }
            

            Just do it!

            S 1 Reply Last reply
            1
            • joeQJ joeQ

              @samdol oh, maybe you should reimplement the drag and drop event. like following code.

              void ListWidget::dragEnterEvent(QDragEnterEvent *event)
              {
                  if (event->mimeData()->hasFormat("image/list-item"))
                      event->accept();
                  else
                      event->ignore();
              }
              
              void ListWidget::dragMoveEvent(QDragMoveEvent *event)
              {
                  if (event->mimeData()->hasFormat("image/list-item")) {
                      event->setDropAction(Qt::MoveAction);
                      event->accept();
                  } else {
                      event->ignore();
                  }
              }
              
              void ListWidget::dropEvent(QDropEvent *event)
              {
                  QListWidgetItem *pItem = NULL;
                  QListWidgetItem *pPosItem = NULL;
                  if (event->mimeData()->hasFormat("image/list-item"))
                  {
                      if( NULL == m_pDragItem )
                      {
                          event->ignore();
                          return;
                      }
                      pPosItem = itemAt( event->pos() );
                      if( NULL == pPosItem )
                      {
                          event->ignore();
                          return;
                      }
              
                      pItem = m_pDragItem->clone();
                      insertItem(row(pPosItem), pItem); ///< insert item
                      event->setDropAction(Qt::MoveAction);
                      m_pDragItem = NULL;
                      event->accept();
                  }
              
              }
              
              void ListWidget::startDrag(Qt::DropActions supportedActions)
              {
                  Q_UNUSED( supportedActions );
              
                  QDrag *pDrag = NULL;
                  QByteArray itemData;
                  QMimeData *pMimeData = NULL;
                  QListWidgetItem *pItem = currentItem();
                  if( NULL == pItem ){return;}
                  if( NULL != m_pDragItem ){return;}
                  if( count() <= 1 ){return;}
                  clearSelection();
              
                  pMimeData = new QMimeData;
                  pMimeData->setData("image/list-item", itemData);
              
                  pDrag = new QDrag(this);
                  pDrag->setMimeData(pMimeData);
              
                  m_bDraging = true;
                  m_pDragItem = pItem;
                  if (pDrag->exec(Qt::MoveAction) == Qt::MoveAction)
                  {
                       /** after the drag and not to delete the item */
                      //delete takeItem(row(pItem)); ///< remove the item
                  }
              
              }
              
              S Offline
              S Offline
              samdol
              wrote on last edited by samdol
              #6

              @joeQ
              Thank you so much for supplying code. But When I put it in my IconView class which is subclassing of QListView, I got the following error messages. Did I put in the wrong place? QIconView uses a subclass of QSortFilterProxyModel. I am using Qt 5.6.2 windows binary.

              error: 'm_pDragItem' was not declared in this scope
              if( NULL == m_pDragItem )
              error: 'itemAt' was not declared in this scope
              pPosItem = itemAt( event->pos() );
              ^
              error: 'm_pDragItem' was not declared in this scope
              pItem = m_pDragItem->clone();
              ^
              ^
              error: 'row' was not declared in this scope
              insertItem(row(pPosItem), pItem); ///< insert item
              ^
              error: 'insertItem' was not declared in this scope
              insertItem(row(pPosItem), pItem); ///< insert item
              ^
              error: 'currentItem' was not declared in this scope
              QListWidgetItem *pItem = currentItem();
              ^
              error: 'm_pDragItem' was not declared in this scope
              if( NULL != m_pDragItem ){return;}
              ^
              error: 'count' was not declared in this scope
              if( count() <= 1 ){return;}
              ^
              error: 'm_bDraging' was not declared in this scope
              m_bDraging = true;
              ^
              error: 'm_pDragItem' was not declared in this scope
              m_pDragItem = pItem;
              ^

              joeQJ 1 Reply Last reply
              0
              • S samdol

                @joeQ
                Thank you so much for supplying code. But When I put it in my IconView class which is subclassing of QListView, I got the following error messages. Did I put in the wrong place? QIconView uses a subclass of QSortFilterProxyModel. I am using Qt 5.6.2 windows binary.

                error: 'm_pDragItem' was not declared in this scope
                if( NULL == m_pDragItem )
                error: 'itemAt' was not declared in this scope
                pPosItem = itemAt( event->pos() );
                ^
                error: 'm_pDragItem' was not declared in this scope
                pItem = m_pDragItem->clone();
                ^
                ^
                error: 'row' was not declared in this scope
                insertItem(row(pPosItem), pItem); ///< insert item
                ^
                error: 'insertItem' was not declared in this scope
                insertItem(row(pPosItem), pItem); ///< insert item
                ^
                error: 'currentItem' was not declared in this scope
                QListWidgetItem *pItem = currentItem();
                ^
                error: 'm_pDragItem' was not declared in this scope
                if( NULL != m_pDragItem ){return;}
                ^
                error: 'count' was not declared in this scope
                if( count() <= 1 ){return;}
                ^
                error: 'm_bDraging' was not declared in this scope
                m_bDraging = true;
                ^
                error: 'm_pDragItem' was not declared in this scope
                m_pDragItem = pItem;
                ^

                joeQJ Offline
                joeQJ Offline
                joeQ
                wrote on last edited by
                #7

                @samdol Hi, friend. My code was copied from my Qt project. And if you want to use it. First you should understand it means. and then modify some code. In my code, It's OK in my project but it is not for you.

                In QListView, has the drag and drop virtual function, you should like me to Re-implementation them. You should to understand the code frame but just to copy it.

                good luck for you!

                Just do it!

                S 1 Reply Last reply
                0
                • joeQJ joeQ

                  @samdol Hi, friend. My code was copied from my Qt project. And if you want to use it. First you should understand it means. and then modify some code. In my code, It's OK in my project but it is not for you.

                  In QListView, has the drag and drop virtual function, you should like me to Re-implementation them. You should to understand the code frame but just to copy it.

                  good luck for you!

                  S Offline
                  S Offline
                  samdol
                  wrote on last edited by
                  #8

                  @joeQ
                  Sorry, But when I click the link, it says
                  Not Found
                  You seem to have stumbled upon a page that does not exist. Return to the home page.
                  Is the link available?

                  joeQJ 1 Reply Last reply
                  0
                  • S samdol

                    @joeQ
                    Sorry, But when I click the link, it says
                    Not Found
                    You seem to have stumbled upon a page that does not exist. Return to the home page.
                    Is the link available?

                    joeQJ Offline
                    joeQJ Offline
                    joeQ
                    wrote on last edited by
                    #9

                    @samdol The link is http://doc.qt.io/qt-5/qlistview.html
                    I just search the QListView class. You can search QListView in qt help. and You will find the drag and drop virtual function.

                    Just do it!

                    S 1 Reply Last reply
                    0
                    • joeQJ joeQ

                      @samdol The link is http://doc.qt.io/qt-5/qlistview.html
                      I just search the QListView class. You can search QListView in qt help. and You will find the drag and drop virtual function.

                      S Offline
                      S Offline
                      samdol
                      wrote on last edited by
                      #10

                      @joeQ

                      Thank you about the link.
                      I followed
                      http://doc.qt.io/qt-5/model-view-programming.html
                      and drag/drop item by MoveAction. It runs
                      bool MyModel::dropMimeData(const QMimeData *data,
                      Qt::DropAction action, int row, int column, const QModelIndex &parent)
                      and drag/drop works fine, except the original item is removed by MoveAction.

                      In order to prevent removing the original item, I reimplemeted the member functions of IconView class which is subclass of QListView. When I did the same drag/drop, it did not run bool MyModel::dropMimeData() function.
                      What should I change to make it run dropMimeData() function?
                      Here is my reimplemented member functions of IconView
                      ,```
                      void startDrag(Qt::DropActions supportedActions)
                      {
                      qDebug()<<"startDrag()";
                      Q_UNUSED( supportedActions );

                          QDrag *pDrag =  new QDrag(this);
                          QByteArray itemData;
                          QMimeData *pMimeData = new QMimeData;
                          pMimeData->setData("application/copy_cut_row.list", itemData);
                          pDrag->setMimeData(pMimeData);
                      
                          Qt::DropAction dropAction = pDrag->exec(Qt::CopyAction | Qt::MoveAction);
                          if (dropAction == Qt::MoveAction)
                          {
                               // after the drag and not to delete the item
                              //delete takeItem(row(pItem)); ///< remove the item
                          }
                      }
                      
                      void dragEnterEvent(QDragEnterEvent *event)
                      {
                          qDebug()<<"dragEnterEvent()";
                          if (event->mimeData()->hasFormat("application/copy_cut_row.list")){
                              qDebug()<<"event->accept();";
                              event->acceptProposedAction();
                             // event->accept();
                          }else{
                              qDebug()<<"event->ignore();";
                              event->ignore();
                          }
                      }
                      void dropEvent(QDropEvent *event)
                       {
                          qDebug()<<"dropEvent()";
                         // event->acceptProposedAction();
                         // IconView *source= qobject_cast<IconView*>(event->source());
                         // if(source && source != this)
                              if (event->mimeData()->hasFormat("application/copy_cut_row.list")){
                                  qDebug()<<"hasFormat";
                                   event->setDropAction(Qt::MoveAction); //To tell the source widget that it can now remove the original version of the dragged item.
                                  event->accept();
                                  //event->acceptProposedAction();
                              }
                       }
                      
                      And I got the following result:
                       I got the following result.
                      startDrag()
                      dragEnterEvent()
                      event->accept();
                      dropEvent()
                      hasFormat
                      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