i am trying to implement a drag and drop feature to PyQt5 QListWidget
it works if self.acceptDrops(True) is in the code but it works on whole application window and wherever i drag file in the window it will add a file to QListWidget...
My goal is to enable drag and drop only on QListWidget area. Please help me with some solution. Unfortunately i am stuck with this.
The Code is:
class okno_glowne(qtw.QWidget):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.ui = Ui_main_new()
self.ui.setupUi(self)
#self.setAcceptDrops(True)
def dragEnterEvent(self, event):
if event.mimeData().hasUrls():
event.accept()
print("Coś się udaje")
else:
event.ignore()
def dropEvent(self, event):
if event.mimeData().hasFormat('application/x-qabstractitemmodeldatalist'):
if event.source() == self.ui.lista_excele_drag:
event.acceptProposedAction()
for url in event.mimeData().urls():
file_path = url.toLocalFile()
self.ui.lista_excele_drag.addItem(file_path)
def mousePressEvent(self, event):
if event.button() == Qt.LeftButton:
self.drag_start_position = event.pos()
def mouseMoveEvent(self, event):
if not (event.buttons() & Qt.LeftButton):
return
if (event.pos() - self.drag_start_position).manhattanLength() <QApplication.startDragDistance():
return
drag = QDrag(self)
mime_data = QMimeData()
mime_data.setText(self.ui.lista_excele_drag.currentItem().text())
drag.setMimeData(mime_data)
drag.exec_(Qt.CopyAction)
if __name__ == '__main__':
app =qtw.QApplication([])
Widget = okno_glowne()
Widget = QtWidgets.QStackedWidget()
w = okno_glowne()
w.show()
app.exec_()
Now the modified code with class in another file named mylistwidget.py
Okay , so i have done a research and i found out promoting widgets is easy ,but not as easy as to implement the code to work :D now , the dragEnter event works fine ( it is printing ) , but the rest as drop and mouse does not...
from PyQt5.QtWidgets import *
from PyQt5.QtCore import Qt
from PyQt5.QtCore import Qt, QMimeData
from PyQt5.QtGui import QDrag
class MyListWidget(QListWidget):
# def __init__(self, *args, **kwargs):
# QListWidget().__init__(self, *args, **kwargs)
def __init__(self, parent=None):
QListWidget().__init__(parent)
self.setAcceptDrops(True)
def dragEnterEvent(self, event):
print("dragEnterEvent")
if event.mimeData().hasUrls():
event.accept()
else:
event.ignore()
def dropEvent(self, event):
print("dropEvent")
if event.mimeData().hasUrls():
for url in event.mimeData().urls():
path = url.toLocalFile()
item = QListWidgetItem(path)
self.addItem(item)
event.accept()
else:
event.ignore()
def mousePressEvent(self, event):
if event.button() == Qt.LeftButton:
self.drag_start_position = event.pos()
def mouseMoveEvent(self, event):
if not (event.buttons() & Qt.LeftButton):
return
if (event.pos() - self.drag_start_position).manhattanLength() < QApplication.startDragDistance():
return
drag = QDrag(self)
mime_data = QMimeData()
mime_data.setText(self.currentItem().text())
drag.setMimeData(mime_data)
drag.exec_(Qt.CopyAction)
Okay i got it...
To override drop function and initialize it i had to add new function:
def dragMoveEvent(self, event):
if event.mimeData().hasUrls():
event.setDropAction(Qt.CopyAction)
event.accept()
else:
event.ignore()
Now it works like a charm.
Thanks for your contribution!