[파이썬] PyQt 드래그 앤 드롭

PyQt is a powerful Python framework for creating desktop applications. One of its many useful features is the ability to implement drag and drop functionality within your application. In this blog post, we will explore how to implement drag and drop using PyQt in a Python application.

Setting up the Environment

Before we start coding, make sure you have installed PyQt on your system. You can install it using pip by running the following command:

pip install PyQt5

Implementing Drag and Drop

To implement drag and drop functionality in PyQt, we need to define two objects: the source object (the widget from which we want to drag items) and the target object (the widget where we want to drop the items).

Source Object

Here’s an example of how to implement drag functionality in a widget:

from PyQt5.QtWidgets import QApplication, QLabel, QWidget, QVBoxLayout
from PyQt5.QtCore import Qt
from PyQt5.QtGui import QDrag

class DraggableWidget(QLabel):
    def __init__(self, text):
        super().__init__(text)
        self.setAcceptDrops(True)

    def mousePressEvent(self, event):
        if event.button() == Qt.LeftButton:
            mime_data = QByteArray()
            drag = QDrag(self)
            drag.setMimeData(mime_data)
            drag.exec_(Qt.MoveAction)

In this example, we create a custom widget DraggableWidget that inherits from QLabel. The important method to implement is mousePressEvent, which is called when the mouse button is pressed. We check if the left button is pressed, create an instance of QDrag, set the mime data (which can contain any custom data you want to transfer), and then execute the drag action.

Target Object

Now let’s implement the target object, where we want to drop the items.

class DropTargetWidget(QWidget):
    def __init__(self):
        super().__init__()
        self.setAcceptDrops(True)
        layout = QVBoxLayout()
        self.setLayout(layout)

    def dragEnterEvent(self, event):
        if event.mimeData().hasFormat('text/plain'):
            event.accept()
        else:
            event.ignore()

    def dropEvent(self, event):
        text = event.mimeData().text()
        label = QLabel(text)
        self.layout().addWidget(label)

In this example, we create a custom widget DropTargetWidget that inherits from QWidget. We set setAcceptDrops(True) to allow dropping on this widget. We implement two methods: dragEnterEvent and dropEvent. In dragEnterEvent, we check if the mime data format matches our desired format (in this case, plain text), and if so, we accept the event; otherwise, we ignore it. In dropEvent, we retrieve the dropped text from the event’s mime data and create a new QLabel widget to display it.

Putting it All Together

To use these widgets, we need to create an instance of each and add them to a layout. Here’s an example of how to do that:

if __name__ == '__main__':
    app = QApplication([])
    draggable_widget = DraggableWidget("Drag me")
    drop_target_widget = DropTargetWidget()

    layout = QVBoxLayout()
    layout.addWidget(draggable_widget)
    layout.addWidget(drop_target_widget)

    main_widget = QWidget()
    main_widget.setLayout(layout)
    main_widget.show()

    app.exec_()

In this example, we create an instance of DraggableWidget and DropTargetWidget, add them to a QVBoxLayout, and then set the main widget’s layout to that layout.

Conclusion

Implementing drag and drop functionality in PyQt can greatly enhance the user experience of your application. By creating a source object to drag items and a target object to accept dropped items, you can create dynamic and interactive interfaces. With the help of PyQt’s extensive documentation and code examples, you can further customize and extend this functionality to suit your specific needs.

Remember to refer to the official PyQt documentation for more details and examples on implementing drag and drop in your PyQt applications. Happy coding!