Profile picture

[Python / GUI] Drag and Drop 기능 구현하기

JaehyoJJAng2024년 09월 13일

개요

PySide6의 QLabel을 활용하여 Drag and Drop 기능을 구현해보려고 한다.
Honeycam 2025-01-14 22-26-02


코드 작성

아래 코드는 PySide6로 Drag-And-Drop을 구현하는 간단한 예제 코드이다.

from PySide6.QtWidgets import QApplication, QLabel, QMainWindow
from PySide6.QtGui import QDragEnterEvent, QDropEvent
from PySide6.QtCore import Qt


class DragDropExample(QMainWindow):
    def __init__(self):
        super().__init__()

        # QLabel 생성 및 설정
        self.label = QLabel("여기로 파일을 드래그 앤 드롭하세요!", self)
        self.label.setGeometry(50, 50, 300, 200)
        self.label.setStyleSheet("background-color: lightgray; border: 2px dashed black;")
        self.label.setAlignment(Qt.AlignmentFlag.AlignCenter)

        # Drag-and-Drop 활성화
        self.label.setAcceptDrops(True)

    def dragEnterEvent(self, event: QDragEnterEvent) -> None:
        """드래그가 시작될 때 호출됩니다."""
        if event.mimeData().hasUrls():  # 드래그된 데이터에 URL(파일 경로)이 포함되어 있는지 확인
            event.accept()
        else:
            event.ignore()

    def dropEvent(self, event: QDropEvent) -> None:
        """드롭이 발생했을 때 호출됩니다."""
        if event.mimeData().hasUrls():  # 드롭된 데이터에 URL이 포함되어 있는지 확인
            files = event.mimeData().urls()  # 드롭된 파일의 경로 리스트
            for file_url in files:
                file_path = file_url.toLocalFile()  # 로컬 파일 경로로 변환
                print(f"드롭된 파일 경로: {file_path}")  # 파일 경로 출력
            event.accept()
        else:
            event.ignore()


if __name__ == "__main__":
    app = QApplication([])

    # 메인 윈도우 설정
    window = DragDropExample()
    window.setWindowTitle("PySide6 Drag and Drop Example")
    window.setGeometry(100, 100, 400, 300)
    window.show()

    app.exec()

코드 설명

Drag-And-Drop 활성화

self.label.setAcceptDrops(True)

QLabel이 드래그 앤 드롭을 수락하도록 설정


dragEnterEvent: 드래그 시작

def dragEnterEvent(self, event: QDragEnterEvent) -> None:
    if event.mimeData().hasUrls():
        event.accept()
    else:
        event.ignore()
  • 드래그가 시작되었을 때 호출됨.
  • event.mimeData().hasUrls()로 드래그된 데이터가 파일인지 확인함.
  • 파일인 경우 event.accept()로 드래그를 허용함.

DropEvent: 드롭 완료

def dropEvent(self, event: QDropEvent) -> None:
    if event.mimeData().hasUrls():
        files = event.mimeData().urls()
        for file_url in files:
            file_path = file_url.toLocalFile()
            print(f"드롭된 파일 경로: {file_path}")
        event.accept()
    else:
        event.ignore()
  • 드롭된 데이터에서 파일 URL을 가져옴.
  • toLocalFile 메서드를 사용하여 로컬 파일 경로로 변환함.
  • 각 파일 경로를 출력합니다.

추가 팁

특정 파일 형식만 허용하려면 event.mimeData().urls()를 필터링 해주도록 하자.

if file_path.endswith(".png") or file_path.endswith(".jpg"):
    print(f"이미지 파일: {file_path}")

QListWidget의 드랍 이벤트 비활성화 문제

QListWidget는 Drop 이벤트가 처리되지 않는다.

drop 이벤트를 활성화해주려면 dragMoveEvent도 수락하도록 따로 설정해줘야 한다.

def drag_move_event(self, event: QDragEnterEvent) -> None:
    if event.mimeData().hasUrls():
        event.accept()
    else:
        event.ignore()

기존 Drag-And-Drop 코드에 해당 메서드를 추가해주면 된다.


Loading script...