드래그 가능한 아이콘 예제

드래그 가능한 아이콘 예시는 동일한 애플리케이션의 위젯 간 또는 다른 애플리케이션 간에 이미지 데이터를 드래그 앤 드롭하는 방법을 보여줍니다.

드래그 앤 드롭이 사용되는 많은 상황에서 사용자는 특정 위젯에서 드래그를 시작하여 페이로드를 다른 위젯에 놓습니다. 이 예제에서는 QLabel 서브클래스를 생성하여 드래그 소스로 사용할 레이블을 만들고 컨테이너와 드롭 사이트 역할을 하는 QWidget안에 배치합니다.

또한 드래그 앤 드롭 작업이 발생할 때 이미지만 전송하는 것이 아니라 그 이상을 전송하고 싶습니다. 사용자가 이미지를 정확하게 드롭 대상에 배치할 수 있도록 사용자가 이미지를 클릭한 위치에 대한 정보도 전송하고 싶습니다. 이 수준의 세부 사항은 데이터에 대한 사용자 정의 MIME 유형을 만들어야 함을 의미합니다.

드래그위젯 클래스 정의

아이콘을 표시하는 데 사용하는 아이콘 위젯은 QLabel 의 하위 클래스입니다:

class DragWidget : public QFrame
{
public:
    explicit DragWidget(QWidget *parent = nullptr);

protected:
    void dragEnterEvent(QDragEnterEvent *event) override;
    void dragMoveEvent(QDragMoveEvent *event) override;
    void dropEvent(QDropEvent *event) override;
    void mousePressEvent(QMouseEvent *event) override;
};

QLabel 클래스는 아이콘에 필요한 대부분의 기능을 제공하므로 드래그 앤 드롭 기능을 제공하기 위해 QWidget::mousePressEvent() 만 다시 구현하면 됩니다.

DragWidget 클래스 구현

DragWidget 생성자는 위젯이 닫힐 때 삭제되도록 하는 속성을 위젯에 설정합니다:

DragWidget::DragWidget(QWidget *parent)
    : QFrame(parent)
{
    setMinimumSize(200, 200);
    setFrameStyle(QFrame::Sunken | QFrame::StyledPanel);
    setAcceptDrops(true);

    QLabel *boatIcon = new QLabel(this);
    boatIcon->setPixmap(QPixmap(":/images/boat.png"));
    boatIcon->move(10, 10);
    boatIcon->show();
    boatIcon->setAttribute(Qt::WA_DeleteOnClose);

    QLabel *carIcon = new QLabel(this);
    carIcon->setPixmap(QPixmap(":/images/car.png"));
    carIcon->move(100, 10);
    carIcon->show();
    carIcon->setAttribute(Qt::WA_DeleteOnClose);

    QLabel *houseIcon = new QLabel(this);
    houseIcon->setPixmap(QPixmap(":/images/house.png"));
    houseIcon->move(10, 80);
    houseIcon->show();
    houseIcon->setAttribute(Qt::WA_DeleteOnClose);
}

아이콘에서 드래그 기능을 사용하려면 마우스 누르기 이벤트에 따라 동작해야 합니다. QWidget::mousePressEvent ()를 다시 구현하고 QDrag 객체를 설정하여 이를 수행합니다.

void DragWidget::mousePressEvent(QMouseEvent *event)
{
    QLabel *child = static_cast<QLabel*>(childAt(event->position().toPoint()));
    if (!child)
        return;

    QPixmap pixmap = child->pixmap();

    QByteArray itemData;
    QDataStream dataStream(&itemData, QIODevice::WriteOnly);
    dataStream << pixmap << QPoint(event->position().toPoint() - child->pos());

아이콘에 대한 픽셀맵 데이터와 아이콘 위젯에서 사용자의 클릭에 대한 정보를 전송할 것이므로 QByteArray 을 구성하고 QDataStream 을 사용하여 세부 정보를 패키지화합니다.

상호 운용성을 위해 드래그 앤 드롭 작업은 MIME 타입을 사용하여 포함된 데이터를 설명합니다. Qt에서는 QMimeData 객체를 사용하여 이 데이터를 설명합니다:

    QMimeData *mimeData = new QMimeData;
    mimeData->setData("application/x-dnditemdata", itemData);

이를 위해 비공식 MIME 타입을 선택하고 QByteArray 을 MIME 데이터 객체에 제공합니다.

드래그 앤 드롭 작업 자체는 QDrag 객체에 의해 처리됩니다:

    QDrag *drag = new QDrag(this);
    drag->setMimeData(mimeData);
    drag->setPixmap(pixmap);
    drag->setHotSpot(event->position().toPoint() - child->pos());

여기서 데이터를 드래그 객체에 전달하고, 작업 중에 커서 옆에 표시될 픽셀맵을 설정하고, 이 픽셀맵의 위치를 커서 아래에 배치하는 핫스팟의 위치를 정의합니다.

예제 프로젝트 @ code.qt.io

© 2025 The Qt Company Ltd. Documentation contributions included herein are the copyrights of their respective owners. The documentation provided herein is licensed under the terms of the GNU Free Documentation License version 1.3 as published by the Free Software Foundation. Qt and respective logos are trademarks of The Qt Company Ltd. in Finland and/or other countries worldwide. All other trademarks are property of their respective owners.