Пример "Delayed Encoding"
Файлы:
Пример "Delayed Encoding" показывает, как задержать подготовку данных для операций перетаскивания пока не будет найдена цель отпускания.
Кнопка Export нажимается чтобы начать перетаскивание. Данные для операции перетаскивания не обрабатываются до тех пор, пока пользователь приложения не найдёт допустимую цель перетаскивания. Это избавляет от избыточной обработки если операция прервана. В нашем случае у нас есть изображение SVG, которое мы хотим отправить как MIME-тип "image/png". Это преобразование из SVG в PNG мы хотим отложить - она может быть достаточно дорогостоящей.
Пример реализован в двух классах: SourceWidget и MimeData. Класс SourceWidget устанавливает ГПИ и начинает операцию перетаскивания по запросу. Класс MimeData, который унаследован от QMimeData, отправляет сигнал когда цель перетаскивания найдена. Этот сигнал соединён со слотом в SourceWidget, который выполняет преобразование из SVG в PNG.
Определение класса SourceWidget
Класс SourceWidget начинает операции перетаскивания, а также выполняет преобразование изображения.
public slots:
void createData(const QString &mimetype);
void startDrag();
private:
QByteArray imageData;
QSvgWidget *imageLabel;
MimeData *mimeData;
Кнопка Export соединена со слотом startDrag(). Слот createData() будет вызываться когда были созданы данные для операции перетаскивания.
Реализация класса SourceWidget
Давайте начнём наш тур по коду со взгляда на слот startDrag().
void SourceWidget::startDrag()
{
mimeData = new MimeData;
connect(mimeData, SIGNAL(dataRequested(const QString &)),
this, SLOT(createData(const QString &)), Qt::DirectConnection);
QDrag *drag = new QDrag(this);
drag->setMimeData(mimeData);
drag->setPixmap(QPixmap(":/images/drag.png"));
drag->exec(Qt::CopyAction);
}
Мы испускаем dataRequested() из MimeData когда операция найдёт доспустимую цель перетаскивания.
Быстро разделаемся с createData():
void SourceWidget::createData(const QString &mimeType)
{
if (mimeType != "image/png")
return;
QImage image(imageLabel->size(), QImage::Format_RGB32);
QPainter painter;
painter.begin(&image);
imageLabel->renderer()->render(&painter);
painter.end();
QByteArray data;
QBuffer buffer(&data);
buffer.open(QIODevice::WriteOnly);
image.save(&buffer, "PNG");
buffer.close();
mimeData->setData("image/png", data);
}
К счастью, Qt предоставляет QSvgRenderer, который может визуализировать изображение SVG на любом QPaintDevice. Также, QImage не имеет проблем сохранения в формат PNG.
В заключение, мы можем передать данные в MimeData.
Определение класса MimeData
Класс MimeData унаследован от QMimeData и делает возможны отложить подготовку данных для операции перетаскивания.
class MimeData : public QMimeData
{
Q_OBJECT
public:
MimeData();
QStringList formats() const;
signals:
void dataRequested(const QString &mimeType) const;
protected:
QVariant retrieveData(const QString &mimetype, QVariant::Type type) const;
};
В следующем разделе мы рассмотрим retrieveData() и formats() подробнее.
Реализация класса MimeData
QStringList MimeData::formats() const
{
return QMimeData::formats() << "image/png";
}
В функции formats() мы возвращаем формат предоставленных нами данных. Это MIME-тип image/png.
QVariant MimeData::retrieveData(const QString &mimeType, QVariant::Type type)
const
{
emit dataRequested(mimeType);
return QMimeData::retrieveData(mimeType, type);
}
retrieveData() переопределена из QMimeData и вызывается когда данные запрошены операцией перетаскивания. К счастью для нас, это произойдёт когда операция завершена, т.е., когда цель перетаскивания найдена.
Мы испускаем сигнал dataRequested(), который принимаем от SourceWidget. SourceWidget (как уже разъяснялось) устанавливает данные в MimeData с помощью setData().
Copyright © 2009 Nokia Corporation and/or its subsidiary(-ies) |
Торговые марки |
Qt 4.5.3 |
|