Details
-
Bug
-
Resolution: Incomplete
-
P3: Somewhat important
-
None
-
6.1.2
-
None
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(); }