Uploaded image for project: 'Qt'
  1. Qt
  2. QTBUG-95804

QListView::dragMoveEvent should allow internal move ; QListView::dropEvent should not replace item

    XMLWordPrintable

    Details

    • Type: Bug
    • Status: Closed
    • Priority: P3: Somewhat important
    • Resolution: Incomplete
    • Affects Version/s: 6.1.2
    • Fix Version/s: None
    • Component/s: Widgets: Itemviews
    • Labels:
      None
    • Platform/s:
      Windows

      Description

      QListView::dragMoveEvent does not allow internal move in IconMode (mouse cursor is Qt::CursorShape::ForbiddenCursor), using QAbstractItemView::dragMoveEvent fixes the problem.

      QListView::dropEvent does not function correctly in IconMode (see the screenshots in attachment), using QAbstractItemView::dropEvent fixes the problem.

      Kit of the screenshots: Desktop Qt 6.1.2 MSVC2019 64bit

       

      here is a working example (using the workarounds):

      mainwindow.h

      #ifndef MAINWINDOW_H
      #define MAINWINDOW_H
      
      #include <QMainWindow>
      #include<QListView>
      
      class ListView:public QListView
      {
          Q_OBJECT
      
      public:
          explicit ListView(QWidget *parent = nullptr): QListView(parent) {}
      
          virtual void dragMoveEvent(QDragMoveEvent *e)override
          {
              QAbstractItemView::dragMoveEvent(e);
          }
      
          virtual void dropEvent(QDropEvent *e)override
          {
              QAbstractItemView::dropEvent(e);
          }
      };
      
      class MainWindow : public QMainWindow
      {
          Q_OBJECT
      
      public:
          explicit MainWindow(QWidget *parent = nullptr);
      };
      
      #endif // MAINWINDOW_H
      

      mainwindow.cpp

      #include "mainwindow.h"
      
      #include<QSplitter>
      #include<QPainter>
      #include<QStandardItemModel>
      
      template<typename T>
      struct type_identity
      {
          using type = T;
      };
      template<typename T>
      using type_identity_t = typename type_identity<T>::type;
      
      MainWindow::MainWindow(QWidget *parent)
          : QMainWindow(parent)
      {
          constexpr auto createQStandardItem=+[](int index)
          {
              QPixmap pixmap(32,32);
              pixmap.fill(Qt::GlobalColor::lightGray);
              {
                  QPainter painter(&pixmap);
                  painter.drawText(QRectF(0,0,32,32),Qt::AlignmentFlag::AlignCenter,QString::number(index));
              }
              QStandardItem*item=new QStandardItem(pixmap,QString::number(index));
              item->setFlags(item->flags()&~Qt::ItemFlag::ItemIsDropEnabled | Qt::ItemFlag::ItemIsDragEnabled);
              return item;
          };
      
          QStandardItemModel*model=new QStandardItemModel();
          model->invisibleRootItem()->setFlags(model->invisibleRootItem()->flags()&~Qt::ItemFlag::ItemIsDragEnabled | Qt::ItemFlag::ItemIsDropEnabled);
          for(int i=0;i!=7;++i)
          {
              model->appendRow(createQStandardItem(i));
          }
      
          QSplitter*splitter=new QSplitter(Qt::Orientation::Horizontal);
          this->setCentralWidget(splitter);
      
          for(int i=0;i!=4;++i)
          {
              QListView*listView=new ListView();
              listView->setModel(model);
              listView->setResizeMode(QListView::ResizeMode::Adjust);
              splitter->addWidget(listView);
      
              listView->setViewMode(type_identity_t<QListView::ViewMode[]>{QListView::ViewMode::ListMode,QListView::ViewMode::ListMode,QListView::ViewMode::IconMode,QListView::ViewMode::IconMode,}[i]);
              listView->setFlow(type_identity_t<QListView::Flow[]>{QListView::Flow::LeftToRight,QListView::Flow::TopToBottom,QListView::Flow::LeftToRight,QListView::Flow::TopToBottom,}[i]);
      
              listView->setDragDropMode(QAbstractItemView::DragDropMode::DragDrop);
              listView->setDefaultDropAction(Qt::DropAction::MoveAction);
              listView->setDropIndicatorShown(true);
              listView->setDragDropOverwriteMode(false);
      
              if(listView->viewMode()==QListView::ViewMode::IconMode)
              {
                  listView->setMovement(QListView::Movement::Snap);
                  listView->setGridSize({50,50});
              }
      
              //"dragEnabled and acceptsDrops are computed by QListView when calling setMovement() or setViewMode()"
              listView->setAcceptDrops(true);
              listView->setDragEnabled(true);
          }
      }
      

      main.cpp

      #include "mainwindow.h"
      
      #include <QApplication>
      
      int main(int argc, char *argv[])
      {
          QApplication a(argc, argv);
          MainWindow w;
          w.show();
          return a.exec();
      }
      

       

        Attachments

        No reviews matched the request. Check your Options in the drop-down menu of this sections header.

          Activity

            People

            Assignee:
            vhilshei Volker Hilsheimer
            Reporter:
            jhcarl0814 Han Jiang
            Votes:
            0 Vote for this issue
            Watchers:
            3 Start watching this issue

              Dates

              Created:
              Updated:
              Resolved:

                Gerrit Reviews

                There are no open Gerrit changes