Qt Forum

    • Login
    • Search
    • Categories
    • Recent
    • Tags
    • Popular
    • Users
    • Groups
    • Search
    • Unsolved

    Update: Forum Guidelines & Code of Conduct

    Unsolved Disable auto remove row in drag drop

    General and Desktop
    3
    10
    3682
    Loading More Posts
    • 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
      samdol last edited by samdol

      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 Reply Quote 0
      • joeQ
        joeQ last edited by

        @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 Reply Quote 0
        • S
          samdol @joeQ last edited by

          @joeQ
          Thanks, but I need both actions.

          joeQ 1 Reply Last reply Reply Quote 0
          • SGaist
            SGaist Lifetime Qt Champion last edited by

            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 Reply Quote 0
            • joeQ
              joeQ @samdol last edited by

              @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 Reply Quote 1
              • S
                samdol @joeQ last edited by 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;
                ^

                joeQ 1 Reply Last reply Reply Quote 0
                • joeQ
                  joeQ @samdol last edited by

                  @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 Reply Quote 0
                  • S
                    samdol @joeQ last edited by

                    @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?

                    joeQ 1 Reply Last reply Reply Quote 0
                    • joeQ
                      joeQ @samdol last edited by

                      @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 Reply Quote 0
                      • S
                        samdol @joeQ last edited by

                        @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 Reply Quote 0
                        • First post
                          Last post