사이트 드롭 예제
이 예는 끌어서 놓기 작업에서 사용할 수 있는 다양한 MIME 형식을 구분하는 방법을 보여줍니다.
사이트 드롭 예제는 다른 애플리케이션에서 드래그 앤 드롭을 허용하고 드래그 객체에서 제공하는 MIME 형식을 표시합니다.
이 예제에는 DropArea
와 DropSiteWindow
두 개의 클래스와 main()
함수가 있습니다. DropArea
객체는 DropSiteWindow
에서 인스턴스화되고, DropSiteWindow
객체는 main()
함수에서 호출됩니다.
DropArea 클래스 정의
DropArea
클래스는 QLabel 의 서브클래스로서 공용 슬롯, clear()
, changed()
시그널을 가지고 있습니다.
class DropArea : public QLabel { Q_OBJECT public: explicit DropArea(QWidget *parent = nullptr); public slots: void clear(); signals: void changed(const QMimeData *mimeData = nullptr);
또한 DropArea
에는 4개의 QWidget 이벤트 핸들러를 재구현한 것이 포함되어 있습니다:
이러한 이벤트 핸들러는 DropArea
클래스의 구현에 자세히 설명되어 있습니다.
protected: void dragEnterEvent(QDragEnterEvent *event) override; void dragMoveEvent(QDragMoveEvent *event) override; void dragLeaveEvent(QDragLeaveEvent *event) override; void dropEvent(QDropEvent *event) override; };
DropArea 클래스 구현
DropArea
생성자에서 minimum size 을 200x200 픽셀로, frame style 을 QFrame::Sunken 과 QFrame::StyledPanel 모두로 설정하고 그 내용을 중앙에 맞춥니다.
DropArea::DropArea(QWidget *parent) : QLabel(parent) { setMinimumSize(200, 200); setFrameStyle(QFrame::Sunken | QFrame::StyledPanel); setAlignment(Qt::AlignCenter); setAcceptDrops(true); setAutoFillBackground(true); clear(); }
또한 acceptDrops 속성을 true
로 설정하여 DropArea
에서 드롭 이벤트를 활성화한 다음 autoFillBackground 속성을 활성화하고 clear()
함수를 호출합니다.
드래그가 진행 중이고 마우스가 DropArea
객체에 들어가면 dragEnterEvent() 이벤트 핸들러가 호출됩니다. DropSite
예제에서는 마우스가 DropArea
에 들어가면 텍스트를 "<콘텐츠 드롭>"으로 설정하고 배경을 강조 표시합니다.
void DropArea::dragEnterEvent(QDragEnterEvent *event) { setText(tr("<drop content>")); setBackgroundRole(QPalette::Highlight); event->acceptProposedAction(); emit changed(event->mimeData()); }
그런 다음 event 에서 acceptProposedAction()를 호출하여 드롭 동작을 제안된 동작으로 설정합니다. 마지막으로, 드롭된 데이터와 해당 MIME 유형 정보를 매개변수로 하여 changed()
신호를 전송합니다.
dragMoveEvent()의 경우 제안된 QDragMoveEvent 객체 event 를 acceptProposedAction()와 함께 수락합니다.
void DropArea::dragMoveEvent(QDragMoveEvent *event) { event->acceptProposedAction(); }
DropArea
클래스의 dropEvent() 구현은 event 의 MIME 데이터를 추출하여 그에 따라 표시합니다.
void DropArea::dropEvent(QDropEvent *event) { const QMimeData *mimeData = event->mimeData();
mimeData
객체에는 이미지, HTML 텍스트, 마크다운 텍스트, 일반 텍스트 또는 URL 목록 중 하나가 포함될 수 있습니다.
if (mimeData->hasImage()) { setPixmap(qvariant_cast<QPixmap>(mimeData->imageData())); } else if (mimeData->hasFormat(u"text/markdown"_s)) { setText(QString::fromUtf8(mimeData->data(u"text/markdown"_s))); setTextFormat(Qt::MarkdownText); } else if (mimeData->hasHtml()) { setText(mimeData->html()); setTextFormat(Qt::RichText); } else if (mimeData->hasText()) { setText(mimeData->text()); setTextFormat(Qt::PlainText); } else if (mimeData->hasUrls()) { QList<QUrl> urlList = mimeData->urls(); QString text; for (qsizetype i = 0, count = qMin(urlList.size(), qsizetype(32)); i < count; ++i) text += urlList.at(i).path() + u'\n'; setText(text); } else { setText(tr("Cannot display data")); }
mimeData
에 이미지가 포함되어 있으면 setPixmap()를 사용하여DropArea
에 이미지를 표시합니다.mimeData
에 HTML이 포함되어 있으면 setText()로 표시하고DropArea
의 텍스트 형식을 Qt::RichText 으로 설정합니다.mimeData
에 마크다운이 포함된 경우 setText()을 사용하여 표시하고DropArea
의 텍스트 형식을 Qt::MarkdownText 으로 설정합니다.mimeData
에 일반 텍스트가 포함된 경우 setText()로 표시하고DropArea
의 텍스트 형식을 Qt::PlainText 으로 설정합니다.mimeData
에 URL이 포함된 경우 URL 목록을 반복하여 개별 줄에 표시합니다.mimeData
에 다른 유형의 객체가 포함된 경우DropArea
의 텍스트와 setText()를 "데이터를 표시할 수 없음"으로 설정하여 사용자에게 알립니다.
그런 다음 DropArea
의 backgroundRole 을 QPalette::Dark 로 설정하고 event
의 제안된 작업을 수락합니다.
setBackgroundRole(QPalette::Dark); event->acceptProposedAction(); }
dragLeaveEvent() 이벤트 핸들러는 드래그가 진행 중이고 마우스가 위젯을 떠날 때 호출됩니다.
void DropArea::dragLeaveEvent(QDragLeaveEvent *event) { clear(); event->accept(); }
DropArea
의 구현에서는 clear()
호출을 지운 다음 제안된 이벤트를 수락합니다.
clear()
함수는 DropArea
의 텍스트를 "<콘텐츠 드롭>"으로 설정하고 backgroundRole 을 QPalette::Dark 으로 설정합니다. 마지막으로 changed()
신호를 전송합니다.
void DropArea::clear() { setText(tr("<drop content>")); setBackgroundRole(QPalette::Dark); emit changed(); }
DropSiteWindow 클래스 정의
DropSiteWindow
클래스에는 생성자와 공용 슬롯인 updateFormatsTable()
이 포함되어 있습니다.
class DropSiteWindow : public QWidget { Q_OBJECT public: DropSiteWindow(); public slots: void updateFormatsTable(const QMimeData *mimeData); void copy(); private: DropArea *dropArea; QLabel *abstractLabel; QTableWidget *formatsTable; QPushButton *clearButton; QPushButton *copyButton; QPushButton *quitButton; QDialogButtonBox *buttonBox; };
또한 이 클래스에는 DropArea
, dropArea
, QLabel, abstractLabel
, QTableWidget, formatsTable
, QDialogButtonBox, buttonBox
의 비공개 인스턴스와 clearButton
및 quitButton
의 두 개의 QPushButton 객체가 포함되어 있습니다.
DropSiteWindow 클래스 구현
DropSiteWindow
의 생성자에서 abstractLabel
을 인스턴스화하고 wordWrap 속성을 true
으로 설정합니다. 또한 adjustSize() 함수를 호출하여 콘텐츠에 따라 abstractLabel
의 크기를 조정합니다.
DropSiteWindow::DropSiteWindow() { abstractLabel = new QLabel(tr("This example accepts drags from other " "applications and displays the MIME types " "provided by the drag object.")); abstractLabel->setWordWrap(true); abstractLabel->adjustSize();
그런 다음 dropArea
를 인스턴스화하고 changed()
신호를 DropSiteWindow
의 updateFormatsTable()
슬롯에 연결합니다.
dropArea = new DropArea; connect(dropArea, &DropArea::changed, this, &DropSiteWindow::updateFormatsTable);
이제 QTableWidget 객체 formatsTable
를 설정합니다. 가로 헤더는 QStringList 객체 labels
를 사용하여 설정합니다. 컬럼 수는 2개로 설정되어 있으며 테이블은 편집할 수 없습니다. 또한 formatTable
의 가로 헤더는 두 번째 열이 늘어나서 사용 가능한 추가 공간을 차지하도록 형식이 지정됩니다.
formatsTable = new QTableWidget; formatsTable->setColumnCount(2); formatsTable->setEditTriggers(QAbstractItemView::NoEditTriggers); formatsTable->setHorizontalHeaderLabels({tr("Format"), tr("Content")}); formatsTable->horizontalHeader()->setStretchLastSection(true);
세 개의 QPushButton 객체( clearButton
, copyButton
, quitButton
)가 인스턴스화되어 QDialogButtonBox 객체인 buttonBox
에 추가됩니다. 여기서는 QDialogButtonBox 을 사용하여 푸시 버튼이 플랫폼의 스타일에 맞는 레이아웃으로 표시되도록 합니다.
clearButton = new QPushButton(tr("Clear")); copyButton = new QPushButton(tr("Copy")); quitButton = new QPushButton(tr("Quit")); buttonBox = new QDialogButtonBox; buttonBox->addButton(clearButton, QDialogButtonBox::ActionRole); buttonBox->addButton(copyButton, QDialogButtonBox::ActionRole); #if !QT_CONFIG(clipboard) copyButton->setVisible(false); #endif buttonBox->addButton(quitButton, QDialogButtonBox::RejectRole); connect(quitButton, &QAbstractButton::clicked, this, &QWidget::close); connect(clearButton, &QAbstractButton::clicked, dropArea, &DropArea::clear); connect(copyButton, &QAbstractButton::clicked, this, &DropSiteWindow::copy);
copyButton
, clearButton
, quitButton
에 대한 clicked() 신호는 각각 copy()
, clear()
, close()에 연결됩니다.
레이아웃의 경우 QVBoxLayout, mainLayout
을 사용하여 위젯을 세로로 정렬합니다. 또한 창 제목을 "드롭 사이트"로 설정하고 최소 크기를 350x500픽셀로 설정합니다.
QVBoxLayout *mainLayout = new QVBoxLayout(this); mainLayout->addWidget(abstractLabel); mainLayout->addWidget(dropArea); mainLayout->addWidget(formatsTable); mainLayout->addWidget(buttonBox); setWindowTitle(tr("Drop Site")); resize(700, 500); }
updateFormatsTable()
함수로 이동합니다. 이 함수는 formatsTable
를 업데이트하여 DropArea
객체에 드롭된 객체의 MIME 형식을 표시합니다. 먼저 QTableWidget 의 rowCount 속성을 0으로 설정합니다. 그런 다음 전달된 QMimeData 객체가 유효한 객체인지 확인합니다.
void DropSiteWindow::updateFormatsTable(const QMimeData *mimeData) { formatsTable->setRowCount(0); copyButton->setEnabled(false); if (!mimeData) return;
mimeData
가 유효하다는 것이 확인되면 지원되는 형식을 반복합니다.
참고: formats() 함수는 mimeData
에서 지원하는 모든 형식을 포함하는 QStringList 객체를 반환합니다.
const QStringList formats = mimeData->formats(); for (const QString &format : formats) { QTableWidgetItem *formatItem = new QTableWidgetItem(format); formatItem->setFlags(Qt::ItemIsEnabled); formatItem->setTextAlignment(Qt::AlignTop | Qt::AlignLeft);
각 반복 내에서 QTableWidgetItem, formatItem
을 생성하고 flags 을 Qt::ItemIsEnabled 으로, text alignment 을 Qt::AlignTop 및 Qt::AlignLeft 으로 설정합니다.
QString 객체 text
은 format
의 내용에 따라 데이터를 표시하도록 사용자 정의됩니다. text
에서 QString 의 simplified() 함수를 호출하여 단어 앞, 뒤 또는 사이에 추가 공백이 없는 문자열을 얻습니다.
QString text; if (format == u"text/plain") { text = mimeData->text().simplified(); } else if (format == u"text/markdown") { text = QString::fromUtf8(mimeData->data(u"text/markdown"_s)); } else if (format == u"text/html") { text = mimeData->html().simplified(); } else if (format == u"text/uri-list") { QList<QUrl> urlList = mimeData->urls(); for (qsizetype i = 0, count = qMin(urlList.size(), qsizetype(32)); i < count; ++i) text.append(urlList.at(i).toString() + u' '); } else { QByteArray data = mimeData->data(format); if (data.size() > 32) data.truncate(32); text = QString::fromLatin1(data.toHex(' ')).toUpper(); }
format
에 URL 목록이 포함된 경우 공백을 사용하여 URL을 구분하여 반복합니다. 반면 format
에 이미지가 포함되어 있으면 텍스트를 16진수로 변환하여 데이터를 표시합니다.
int row = formatsTable->rowCount(); formatsTable->insertRow(row); formatsTable->setItem(row, 0, new QTableWidgetItem(format)); formatsTable->setItem(row, 1, new QTableWidgetItem(text)); } formatsTable->resizeColumnToContents(0); #if QT_CONFIG(clipboard) copyButton->setEnabled(formatsTable->rowCount() > 0); #endif }
text
에 적절한 데이터가 포함되도록 사용자 정의한 후에는 format
과 text
를 모두 formatsTable
에 setItem()로 삽입합니다. 마지막으로 formatsTable
의 첫 번째 열에 resizeColumnToContents()를 호출합니다.
main() 함수
main()
함수 내에서 DropSiteWindow
을 인스턴스화하고 show() 함수를 호출합니다.
int main(int argc, char *argv[]) { QApplication app(argc, argv); DropSiteWindow window; window.show(); return app.exec(); }
© 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.