I am having trouble with the dragging of items inside a QListWidget, the items which are selected are stuck with the mouse cursor even after the mouse button is released. I want to reorder the items inside the QListWidget by dragging them though mouse while the mouse left button is pressed.
I have promoted my ui->listwidget to a custom listwidget to accept drag and drops.

Qt Code:
  1. #ifndef PROJECTLISTWIDGET_H
  2. #define PROJECTLISTWIDGET_H
  3.  
  4. class ProjectListWidget : public QListWidget
  5. {
  6. Q_OBJECT
  7. public:
  8. ProjectListWidget(QWidget *parent = 0);
  9.  
  10. signals:
  11. void itemDrag();
  12.  
  13. protected:
  14. void mousePressEvent(QMouseEvent *event);
  15. void mouseMoveEvent(QMouseEvent *event);
  16. void dragEnterEvent(QDragEnterEvent *event);
  17. void dragMoveEvent(QDragMoveEvent *event);
  18. void dropEvent(QDropEvent *event);
  19. void performDrag();
  20. QPoint startPos;
  21. };
  22.  
  23.  
  24. #endif // PROJECTLISTWIDGET_H
To copy to clipboard, switch view to plain text mode 

Qt Code:
  1. #include "projectlistwidget.h"
  2.  
  3. using namespace std;
  4.  
  5. ProjectListWidget::ProjectListWidget(QWidget *parent)
  6. : QListWidget(parent)
  7. {
  8. setAcceptDrops(true);
  9. setDragEnabled(true);
  10. }
  11.  
  12. void ProjectListWidget::mousePressEvent(QMouseEvent *event)
  13. {
  14. if (event->button() == Qt::LeftButton)
  15. {
  16. startPos = event->pos();
  17. }
  18. QListWidget::mousePressEvent(event);
  19.  
  20. }
  21.  
  22. void ProjectListWidget::mouseMoveEvent(QMouseEvent *event)
  23. {
  24. if (event->buttons() & Qt::LeftButton)
  25. {
  26. int distance = (event->pos() - startPos).manhattanLength();
  27. if (distance >= QApplication::startDragDistance())
  28. {
  29. performDrag();
  30. }
  31. }
  32. QListWidget::mouseMoveEvent(event);
  33. }
  34.  
  35. void ProjectListWidget::performDrag()
  36. {
  37. QListWidgetItem *item = currentItem();
  38. if (item) {
  39. QMimeData *mimeData = new QMimeData;
  40. mimeData->setText(item->text());
  41. QDrag *drag = new QDrag(this);
  42. drag->setMimeData(mimeData);
  43. emit itemDrag();
  44. if (drag->exec(Qt::MoveAction) == Qt::CopyAction)
  45. delete item;
  46. }
  47. }
  48.  
  49. void ProjectListWidget::dragEnterEvent(QDragEnterEvent *event)
  50. {
  51. if (event->mimeData()->hasUrls())
  52. {
  53. event->acceptProposedAction();
  54. } else
  55. {
  56. QListWidget::dragEnterEvent(event);
  57. }
  58. }
  59.  
  60. void ProjectListWidget::dragMoveEvent(QDragMoveEvent *event)
  61. {
  62. if (event->mimeData()->hasUrls() & Qt::LeftButton)
  63. {
  64. event->acceptProposedAction();
  65. } else
  66. {
  67. QListWidget::dragMoveEvent(event);
  68. }
  69. }
  70.  
  71. void ProjectListWidget::dropEvent(QDropEvent *event)
  72. {
  73. if (event->mimeData()->hasUrls())
  74. {
  75. QList<QUrl> urls = event->mimeData()->urls();
  76. if (!urls.isEmpty())
  77. {
  78. QUrl url;
  79. foreach (url,urls)
  80. {
  81. new QListWidgetItem(url.toLocalFile(),this);
  82. emit itemDrag();
  83. }
  84. }
  85. event->acceptProposedAction();
  86. }
  87. QListWidget::dropEvent(event);
  88. }
To copy to clipboard, switch view to plain text mode 

listbox.jpeg