This article is divided into two parts, the first part through the python3 + PyQt5 to realize the drag and drop operation of custom data. The second part of the first part of the program is modified to increase the drag and drop operation, the menu prompts whether to move or copy, there can be ctrl keyboard to set the move process to copy the source instead of deleting the source.
The custom data MIME data type QMimeData, MIME is a standardized format for handling custom data with multiple components.MIME data consists of a data type and a subtype-for example, text/plain, text/html, image/png.To handle custom MIME data consists of a data type and a subtype-for example, text/plain, text/html, image/png. To work with custom MIME data, you must choose a custom data type and a subtype, and then encapsulate the data in a QMimeData object. In this example, we create new MIME data of type application/x-icon-and-text.
Notes:
dragEnterEvent This is a drag and drop event function, we drag and drop the file into the program interface to open, before you must setAcceptDrops(true) after dragging and dropping, but only set acceptDrops is not enough, you also need to dragEnterEvent event in the dragged object to screen, determine the mimeData is of a type you can handle, and if so, call () to release it. The dropEvent event is generated at the end of the drag and drop, where the final placement operation is performed. In short this is a drag and drop event function that filters events and places them.
Part I:
#!/usr/bin/env python3 import os import sys from import (QByteArray, QDataStream, QIODevice, QMimeData, QPoint, QSize, Qt) from import (QApplication, QDialog,QGridLayout, QLineEdit, QListWidget,QListWidgetItem, QWidget) from import QIcon,QColor,QPainter,QFontMetricsF,QDrag class DropLineEdit(QLineEdit): def __init__(self, parent=None): super(DropLineEdit, self).__init__(parent) (True) def dragEnterEvent(self, event): if ().hasFormat("application/x-icon-and-text"): () else: () def dragMoveEvent(self, event): if ().hasFormat("application/x-icon-and-text"): () () else: () def dropEvent(self, event): if ().hasFormat("application/x-icon-and-text"): data = ().data("application/x-icon-and-text") stream = QDataStream(data, ) text = "" #stream >> text text=() (text) () () else: () class DnDListWidget(QListWidget): def __init__(self, parent=None): super(DnDListWidget, self).__init__(parent) (True) (True) def dragEnterEvent(self, event): if ().hasFormat("application/x-icon-and-text"): () else: () def dragMoveEvent(self, event): if ().hasFormat("application/x-icon-and-text"): () () else: () def dropEvent(self, event): if ().hasFormat("application/x-icon-and-text"): data = ().data("application/x-icon-and-text") stream = QDataStream(data, ) text = "" icon = QIcon() #stream >> text >> icon text=() stream >> icon item = QListWidgetItem(text, self) (icon) () () else: () def startDrag(self, dropActions): item = () icon = () data = QByteArray() stream = QDataStream(data, ) #stream << () << icon (()) stream << icon mimeData = QMimeData() ("application/x-icon-and-text", data) drag = QDrag(self) (mimeData) pixmap = (24, 24) (QPoint(12, 12)) (pixmap) if () == : ((item)) class DnDWidget(QWidget): def __init__(self, text, icon=QIcon(), parent=None): super(DnDWidget, self).__init__(parent) (True) = text = icon def minimumSizeHint(self): fm = QFontMetricsF(()) if (): return QSize((), () * 1.5) return QSize(34 + (), max(34, () * 1.5)) def paintEvent(self, event): height = QFontMetricsF(()).height() painter = QPainter(self) () () ((), QColor().lighter()) if (): (10, height, ) else: pixmap = (24, 24) (0, 5, pixmap) (34, height, + " (Drag to or from me!)") def dragEnterEvent(self, event): if ().hasFormat("application/x-icon-and-text"): () else: () def dragMoveEvent(self, event): if ().hasFormat("application/x-icon-and-text"): () () else: () def dropEvent(self, event): if ().hasFormat("application/x-icon-and-text"): data = ().data("application/x-icon-and-text") stream = QDataStream(data, ) = "" = QIcon() #stream >> >> =() stream>> () () () () else: () def mouseMoveEvent(self, event): () (self, event) def startDrag(self): icon = if (): return data = QByteArray() stream = QDataStream(data, ) #stream << << icon () stream<<icon mimeData = QMimeData() ("application/x-icon-and-text", data) drag = QDrag(self) (mimeData) pixmap = (24, 24) (QPoint(12, 12)) (pixmap) () class Form(QDialog): def __init__(self, parent=None): super(Form, self).__init__(parent) dndListWidget = DnDListWidget() path = (__file__) for image in sorted(((path, "images"))): if (".png"): item = QListWidgetItem((".")[0].capitalize()) (QIcon((path, "images/{0}".format(image)))) (item) dndIconListWidget = DnDListWidget() () dndWidget = DnDWidget("Drag to me!") dropLineEdit = DropLineEdit() layout = QGridLayout() (dndListWidget, 0, 0) (dndIconListWidget, 0, 1) (dndWidget, 1, 0) (dropLineEdit, 1, 1) (layout) ("Custom Drag and Drop") if __name__ == "__main__": app = QApplication() form = Form() () app.exec_()
Run results:
Part II:
#!/usr/bin/env python3 import os import sys from import (QByteArray, QDataStream, QIODevice, QMimeData, QPoint, QSize, Qt) from import (QApplication, QDialog,QGridLayout, QLineEdit, QListWidget,QListWidgetItem, QWidget,QMenu) from import QIcon,QColor,QPainter,QFontMetricsF,QDrag,QCursor class DropLineEdit(QLineEdit): def __init__(self, parent=None): super(DropLineEdit, self).__init__(parent) (True) def dragEnterEvent(self, event): if ().hasFormat("application/x-icon-and-text"): () else: () def dragMoveEvent(self, event): if ().hasFormat("application/x-icon-and-text"): () () else: () def dropEvent(self, event): if ().hasFormat("application/x-icon-and-text"): data = ().data("application/x-icon-and-text") stream = QDataStream(data, ) text = "" text=() (text) () () else: () class DnDMenuListWidget(QListWidget): def __init__(self, parent=None): super(DnDMenuListWidget, self).__init__(parent) (True) (True) = def dragEnterEvent(self, event): if ().hasFormat("application/x-icon-and-text"): () else: () def dragMoveEvent(self, event): if ().hasFormat("application/x-icon-and-text"): () () else: () def dropEvent(self, event): if ().hasFormat("application/x-icon-and-text"): data = ().data("application/x-icon-and-text") stream = QDataStream(data, ) text = "" icon = QIcon() text=() stream>>icon menu = QMenu(self) ("&Copy", ) ("&Move", ) if menu.exec_(()): item = QListWidgetItem(text, self) (icon) () () return else: () () def setCopyAction(self): = def setMoveAction(self): = def startDrag(self, dropActions): item = () icon = () data = QByteArray() stream = QDataStream(data, ) (()) stream<<icon mimeData = QMimeData() ("application/x-icon-and-text", data) drag = QDrag(self) (mimeData) pixmap = (24, 24) (QPoint(12, 12)) (pixmap) if ((|) == ): ((item)) class DnDCtrlListWidget(QListWidget): def __init__(self, parent=None): super(DnDCtrlListWidget, self).__init__(parent) (True) (True) def dragEnterEvent(self, event): if ().hasFormat("application/x-icon-and-text"): () else: () def dragMoveEvent(self, event): if ().hasFormat("application/x-icon-and-text"): action = if () & : action = (action) () else: () def dropEvent(self, event): if ().hasFormat("application/x-icon-and-text"): data = ().data("application/x-icon-and-text") stream = QDataStream(data, ) text = "" icon = QIcon() text=() stream>>icon item = QListWidgetItem(text, self) (icon) action = if () & : action = (action) () else: () def startDrag(self, dropActions): item = () icon = () data = QByteArray() stream = QDataStream(data, ) (()) stream<<icon mimeData = QMimeData() ("application/x-icon-and-text", data) drag = QDrag(self) (mimeData) pixmap = (24, 24) (QPoint(12, 12)) (pixmap) if ((|) == ): ((item)) class DnDWidget(QWidget): def __init__(self, text, icon=QIcon(), parent=None): super(DnDWidget, self).__init__(parent) (True) = text = icon def minimumSizeHint(self): fm = QFontMetricsF(()) if (): return QSize((), () * 1.5) return QSize(34 + (), max(34, () * 1.5)) def paintEvent(self, event): height = QFontMetricsF(()).height() painter = QPainter(self) () () ((), QColor().lighter()) if (): (10, height, ) else: pixmap = (24, 24) (0, 5, pixmap) (34, height, + " (Drag to or from me!)") def dragEnterEvent(self, event): if ().hasFormat("application/x-icon-and-text"): () else: () def dragMoveEvent(self, event): if ().hasFormat("application/x-icon-and-text"): () () else: () def dropEvent(self, event): if ().hasFormat("application/x-icon-and-text"): data = ().data("application/x-icon-and-text") stream = QDataStream(data, ) = "" = QIcon() =() stream>> () () () () else: () def mouseMoveEvent(self, event): () (self, event) def startDrag(self): icon = if (): return data = QByteArray() stream = QDataStream(data, ) () stream<<icon mimeData = QMimeData() ("application/x-icon-and-text", data) drag = QDrag(self) (mimeData) pixmap = (24, 24) (QPoint(12, 12)) (pixmap) () class Form(QDialog): def __init__(self, parent=None): super(Form, self).__init__(parent) dndListWidget = DnDMenuListWidget() path = (__file__) for image in sorted(((path, "images"))): if (".png"): item = QListWidgetItem((".")[0].capitalize()) (QIcon((path, "images/{0}".format(image)))) (item) dndIconListWidget = DnDCtrlListWidget() () dndWidget = DnDWidget("Drag to me!") dropLineEdit = DropLineEdit() layout = QGridLayout() (dndListWidget, 0, 0) (dndIconListWidget, 0, 1) (dndWidget, 1, 0) (dropLineEdit, 1, 1) (layout) ("Custom Drag and Drop") if __name__ == "__main__": app = QApplication() form = Form() () app.exec_()
Run results:
This is the whole content of this article.