Пример "Drop Site"Файлы:
Пример показывает, как различать различные MIME-форматы доступные в операциях перетаскивания. Пример "Drop Site" принимает отпускания из других приложений и выводит на экран MIME-форматы, предоставляемые объектом перетаскивания. В данном примере имеется два класса, DropArea и DropSiteWindow, и функция main(). Объект DropArea создаётся в DropSiteWindow; объект DropSiteWindow затем вызывается в функции main(). Определение класса DropAreaКласс DropArea является подклассом QLabel с открытым слотом clear() и сигналом changed(). class DropArea : public QLabel { Q_OBJECT public: DropArea(QWidget *parent = 0); public slots: void clear(); signals: void changed(const QMimeData *mimeData = 0); Кроме того, DropArea также содержит закрытый экземпляр класса QLabel и переопределения четырёх обработчиков событий QWidget: Эти обработчики событий объяснены далее в реализации класса DropArea. protected: void dragEnterEvent(QDragEnterEvent *event); void dragMoveEvent(QDragMoveEvent *event); void dragLeaveEvent(QDragLeaveEvent *event); void dropEvent(QDropEvent *event); private: QLabel *label; }; Реализация класса DropAreaВ конструкторе DropArea мы устанавливаем минимальный размер равным 200x200 пикселям, стиль рамки равным 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(); } Также мы включаем события отпускания в DropArea установив свойство acceptDrops равным true. Затем мы включаем свойство autoFillBackground и вызываем функцию clear(). Обработчик событий dragEnterEvent() вызывается когда выполняется перетаскивание и мышь входит в пределы объекта DropArea. Для примера DropSite, когда мышь входит в пределы DropArea, мы устанавливаем его текст равным "<drop content>" и подсвечиваем фон. void DropArea::dragEnterEvent(QDragEnterEvent *event) { setText(tr("<drop content>")); setBackgroundRole(QPalette::Highlight); event->acceptProposedAction(); emit changed(event->mimeData()); } Затем мы вызываем acceptProposedAction() на event, устанавливаем действия отпускания для предлагаемого действия. В заключение, мы испускаем сигнал changed() с данными, которые были отпущены, и информацией об их MIME-типе в качестве параметра. Для dragMoveEvent() мы только принимаем предложенный объект QDragMoveEvent, event, с помощью acceptProposedAction(). void DropArea::dragMoveEvent(QDragMoveEvent *event) { event->acceptProposedAction(); } Реализация класса DropArea функции dropEvent() извлекает mime-данные event'а и, соответственно, выводит их на экран. 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->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 (int i = 0; i < urlList.size() && i < 32; ++i) { QString url = urlList.at(i).path(); text += url + QString("\n"); } setText(text); } else { setText(tr("Cannot display data")); }
Затем установим роль DropArea'а, backgroundRole, в значение QPalette::Dark и примем предлагаемой действие event'а. setBackgroundRole(QPalette::Dark); event->acceptProposedAction(); } Обработчик событий dragLeaveEvent() вызывается когда происходит перетаскивание и мышь покидает пределы виджета. void DropArea::dragLeaveEvent(QDragLeaveEvent *event) { clear(); event->accept(); } Для реализации DropArea мы очищаем, вызывая clear(), а затем принимаем предложенное событие. Функция clear() устанавливает текст в DropArea в значение "<drop content>" и устанавливает 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); private: DropArea *dropArea; QLabel *abstractLabel; QTableWidget *formatsTable; QPushButton *clearButton; QPushButton *quitButton; QDialogButtonBox *buttonBox; }; Класс также содержит закрытый экземпляр класса DropArea, dropArea, QLabel, abstractLabel, QTableWidget, formatsTable, QDialogButtonBox, buttonBox, а также два объекта QPushButton, clearButton и quitButton. Реализация класса 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, SIGNAL(changed(const QMimeData*)), this, SLOT(updateFormatsTable(const QMimeData*))); Теперь мы устанавливаем объект QTableWidget, formatsTable. Его горизонтальный заголовок устанавливается используя объект QStringList, labels. Количество колонок устанавливается равным двум, а таблица - нередактируемой. Также, горизонтальный заголовок formatTable'а форматируется чтобы обеспечить растяжение его второго столбца на всё доступное дополнительное пространство. QStringList labels; labels << tr("Format") << tr("Content"); formatsTable = new QTableWidget; formatsTable->setColumnCount(2); formatsTable->setEditTriggers(QAbstractItemView::NoEditTriggers); formatsTable->setHorizontalHeaderLabels(labels); formatsTable->horizontalHeader()->setStretchLastSection(true); Два объект QPushButton, clearButton и quitButton, создаются и добавляются в объект buttonBox класса QDialogButtonBox. Мы используем QDialogButtonBox, чтобы убедиться, что кнопки присутствуют в компоновке, которая согласовывается со стилем платформы. clearButton = new QPushButton(tr("Clear")); quitButton = new QPushButton(tr("Quit")); buttonBox = new QDialogButtonBox; buttonBox->addButton(clearButton, QDialogButtonBox::ActionRole); buttonBox->addButton(quitButton, QDialogButtonBox::RejectRole); connect(quitButton, SIGNAL(pressed()), this, SLOT(close())); connect(clearButton, SIGNAL(pressed()), dropArea, SLOT(clear())); Сигналы clicked() для quitButton и clearButton присоединяются к close() и clear(), соответственно. Для компоновки мы используем QVBoxLayout, mainLayout, чтобы разместить наши виджеты вертикально. Также мы устанавливаем заголовок окна в "Drop Site" и минимальный размер равным 350x500 пикселям. QVBoxLayout *mainLayout = new QVBoxLayout; mainLayout->addWidget(abstractLabel); mainLayout->addWidget(dropArea); mainLayout->addWidget(formatsTable); mainLayout->addWidget(buttonBox); setLayout(mainLayout); setWindowTitle(tr("Drop Site")); setMinimumSize(350, 500); } Мы переходим к функции updateFormatsTable(). Эта функция обновляет formatsTable, выводя на экран MIME-форматы объекта, отпускаемого на объект DropArea. Сначала мы устанавливаем свойство QTableWidget'а, rowCount, равным 0. Затем мы проверяем правильность, чтобы убедиться, что объект QMimeData передан в правильный объект. void DropSiteWindow::updateFormatsTable(const QMimeData *mimeData) { formatsTable->setRowCount(0); if (!mimeData) return; Раз уж мы уверены, что mimeData правилен, мы перебираем поддерживаемые им форматы используя ключевое слово foreach. Ключевое слово имеет следующий формат: foreach(переменная, контейнер) В нашем примере, format - переменная, а контейнер - QStringList, полученный из mimeData->formats(). Замечание: Функция formats() возвращает объект QStringList, содержащий все форматы, поддерживаемые mimeData. foreach (QString format, mimeData->formats()) { QTableWidgetItem *formatItem = new QTableWidgetItem(format); formatItem->setFlags(Qt::ItemIsEnabled); formatItem->setTextAlignment(Qt::AlignTop | Qt::AlignLeft); В каждой итерации мы создаём QTableWidgetItem, formatItem и устанавливаем его флаги равными Qt::ItemIsEnabled, а его выравнивание текста - в Qt::AlignTop и Qt::AlignLeft. Объект QString object, text, настраивается для вывода на экран данных, согласно содержимого format. Мы вызываем функцию {QString}'а, simplified(), на text, чтобы получить строку, которая не имеет дополнительного пробела перед, после или между словами. QString text; if (format == "text/plain") { text = mimeData->text().simplified(); } else if (format == "text/html") { text = mimeData->html().simplified(); } else if (format == "text/uri-list") { QList<QUrl> urlList = mimeData->urls(); for (int i = 0; i < urlList.size() && i < 32; ++i) text.append(urlList[i].toString() + " "); } else { QByteArray data = mimeData->data(format); for (int i = 0; i < data.size() && i < 32; ++i) { QString hex = QString("%1").arg(uchar(data[i]), 2, 16, QChar('0')) .toUpper(); text.append(hex + " "); } } Если format содержит список URLов, мы перебираем их, используя пробелы как разделители. С другой стороны, если format содержит изображение, мы выводим на экран данные, преобразовав текст в шестнадцатеричный вид. int row = formatsTable->rowCount(); formatsTable->insertRow(row); formatsTable->setItem(row, 0, new QTableWidgetItem(format)); formatsTable->setItem(row, 1, new QTableWidgetItem(text)); } formatsTable->resizeColumnToContents(0); } Так как text настроен для содержания в себе соответствующих данных, мы вставляем и format, и text в formatsTable с помощью setItem(). В заключение, мы вызываем resizeColumnToContents() на первом столбце formatsTable'а. Функция main()В функции main() мы создаём экземпляр DropSiteWindow и вызываем его функцию show(). int main(int argc, char *argv[]) { QApplication app(argc, argv); DropSiteWindow window; window.show(); return app.exec(); } |
Попытка перевода Qt документации. Если есть желание присоединиться, или если есть замечания или пожелания, то заходите на форум: Перевод Qt документации на русский язык... Люди внесшие вклад в перевод: Команда переводчиков |