×
Namespaces

Variants
Actions
(Difference between revisions)

如何 通过QGalleryQueryModel 制作一个简单的图片浏览器

From Nokia Developer Wiki
Jump to: navigation, search
liuting (Talk | contribs)
(Liuting - - 代码实现)
renlin (Talk | contribs)
(Renlin -)
 
(4 intermediate revisions by 2 users not shown)
Line 1: Line 1:
[[Category:Draft]]
+
[[Category:Qt]][[Category:Qt Mobility]][[Category:Imaging]][[Category:Symbian]][[Category:MeeGo Harmattan]][[Category:Lang-Chinese]]
''Delete instructional text in italic''
+
 
+
{{Abstract|This article explains how to ... }} ''Replace the abstract text with a short paragraph (or sentence) describing what the topic covers.''
+
 
+
''Enter article metadata as described below. Note that this template can be placed anywhere in the article. Do not remove parameters that you do not use''
+
 
{{ArticleMetaData <!-- v1.2 -->
 
{{ArticleMetaData <!-- v1.2 -->
|sourcecode= <!-- Link to example source code e.g. [[Media:The Code Example ZIP.zip]] -->
+
|sourcecode= [[Media:Mediabrowser.zip]]  
 
|installfile= <!-- Link to installation file (e.g. [[Media:The Installation File.sis]]) -->
 
|installfile= <!-- Link to installation file (e.g. [[Media:The Installation File.sis]]) -->
 
|devices= <!-- Devices tested against - e.g. ''devices=Nokia 6131 NFC, Nokia C7-00'') -->
 
|devices= <!-- Devices tested against - e.g. ''devices=Nokia 6131 NFC, Nokia C7-00'') -->
Line 12: Line 7:
 
|platform= <!-- Compatible platforms - e.g. Symbian^1 and later, Qt 4.6 and later -->
 
|platform= <!-- Compatible platforms - e.g. Symbian^1 and later, Qt 4.6 and later -->
 
|devicecompatability= <!-- Compatible devices e.g.: All* (must have internal GPS) -->
 
|devicecompatability= <!-- Compatible devices e.g.: All* (must have internal GPS) -->
|dependencies= <!-- Any other/external dependencies e.g.: Google Maps Api v1.0 -->  
+
|dependencies= <!-- Any other/external dependencies e.g.: Google Maps Api v1.0 -->
|signing=<!-- Signing requirements - empty or one of: Self-Signed, DevCert, Manufacturer -->
+
|signing= <!-- Signing requirements - empty or one of: Self-Signed, DevCert, Manufacturer -->
 
|capabilities= <!-- Capabilities required by the article/code example (e.g. Location, NetworkServices. -->
 
|capabilities= <!-- Capabilities required by the article/code example (e.g. Location, NetworkServices. -->
 
|keywords= <!-- APIs, classes and methods (e.g. QSystemScreenSaver, QList, CBase -->
 
|keywords= <!-- APIs, classes and methods (e.g. QSystemScreenSaver, QList, CBase -->
|language= <!-- Language category code for non-English topics - e.g. Lang-Chinese -->
+
|language= Lang-Chinese
 
|translated-by= <!-- [[User:XXXX]] -->
 
|translated-by= <!-- [[User:XXXX]] -->
|translated-from-title= <!-- Title only -->  
+
|translated-from-title= <!-- Title only -->
 
|translated-from-id= <!-- Id of translated revision -->
 
|translated-from-id= <!-- Id of translated revision -->
|review-by=<!-- After re-review: [[User:username]] -->
+
|review-by= <!-- After re-review: [[User:username]] -->
 
|review-timestamp= <!-- After re-review: YYYYMMDD -->
 
|review-timestamp= <!-- After re-review: YYYYMMDD -->
 
|update-by= <!-- After significant update: [[User:username]]-->
 
|update-by= <!-- After significant update: [[User:username]]-->
 
|update-timestamp= <!-- After significant update: YYYYMMDD -->
 
|update-timestamp= <!-- After significant update: YYYYMMDD -->
|creationdate= <!-- Format YYYYMMDD -->
+
|creationdate= 20120328
|author= <!-- Display as link [[User:username]] -->
+
|author= [[User:Liuting]]
 
}}
 
}}
  
Line 211: Line 206:
  
 
== 代码下载==
 
== 代码下载==
 +
[[file:Mediabrowser.zip]]
 +
 
== 相关链接 ==
 
== 相关链接 ==
  
 
''Add categories below. Remove Category:Draft when the page is complete or near complete''
 
''Add categories below. Remove Category:Draft when the page is complete or near complete''
 +
[[Category:Code Examples]]

Latest revision as of 06:18, 11 July 2012

Article Metadata

代码示例
兼容于
平台:
Symbian

文章
liuting 在 28 Mar 2012 创建
最后由 renlin 在 11 Jul 2012 编辑

Contents

[edit] 介绍

QML 提供了一个 plugin DocumentGalleryMode ,通过使用这个plugin,我们可以很简单的实现一个图片浏览器,但是随着图片的增加,我们会发现加载速度十分缓慢,用户体验很差,这是由于QML 内部实现采取高质量的平滑缩放耗时很长,所以我们不的不重新实现自己的model ,并在线程中通过QImageReader 实现大量图片的快速缩放。接下来我们通过代码片段来看下具体的实现过程

[edit] 代码实现

[edit] ThumbnailModel.h

class ThumbnailModel : public QGalleryQueryModel
{
Q_OBJECT
public:
static const QSize thumbnailSize;
 
ThumbnailModel(QAbstractGallery *gallery, QObject *parent = 0);
~ThumbnailModel();
 
QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const;
 
protected:
virtual QUrl imageUrl(const QModelIndex &index) const;
 
private slots:
void thumbnailLoaded();
 
private:
mutable ThumbnailCache cache;
 
};
<code>
首先我们必须从 QGalleryQueryModel 派生一个类,并且重写data()方法
===ThumbnailModel.cpp===
<code>
QVariant ThumbnailModel::data(const QModelIndex &index, int role) const
{
qDebug()<<"enter data";
return role == Qt::DecorationRole && index.isValid()
 ? cache.thumbnail(imageUrl(index))
 : QGalleryQueryModel::data(index, role);
}
void ThumbnailModel::thumbnailLoaded()
{
emit dataChanged(index(0, 0), index(rowCount() - 1, columnCount() -1));
}

在data 函数中我们返回已经缩放好的图片, 以便VIEW绘制。在thumbnailLoaded()函数中我们需要发送一个信号通知VIEW MODEL中的数据有所更新,以便VIEW进行更新。

[edit] thumbnailcache.h

class ThumbnailCache : public QThread
{
Q_OBJECT
public:
ThumbnailCache(QObject *parent = 0);
~ThumbnailCache();
 
QString thumbnail(const QUrl &url);
 
bool event(QEvent *event);
 
signals:
void thumbnailReady();
 
protected:
void run();
 
private:
QImage loadImage(const QUrl &url) const;
QString thumbnailPath(const QUrl &url) const;
 
QMutex mutex;
QWaitCondition waitCondition;
QCache<QUrl, Thumbnail> cache;
QQueue<QUrl> pendingUrls;
bool cancelled;
};

我们需要定义一个线程类,在run函数中实现图片的缩放

[edit] thumbnailcache.cpp

QImage ThumbnailCache::loadImage(const QUrl &url) const
{
const QString fileName = thumbnailPath(url);
 
QImageReader reader(fileName);
reader.setQuality(25);
 
if (reader.supportsOption(QImageIOHandler::Size)) {
QSize size = reader.size();
 
if (!reader.supportsOption(QImageIOHandler::ScaledSize)
&& (size.width() > 1280 || size.height() > 1280)) {
return QImage();
}
 
if (size.width() > ThumbnailModel::thumbnailSize.width()
|| size.height() > ThumbnailModel::thumbnailSize.height()) {
size.scale(ThumbnailModel::thumbnailSize, Qt::KeepAspectRatio);
}
 
reader.setScaledSize(size);
} else {
reader.setScaledSize(ThumbnailModel::thumbnailSize);
}
 
return reader.read();
}

我们将在loadImage()函数中通过QImageReader 对图片进行快速缩放

[edit] photodelegate.h

#ifndef PHOTODELEGATE_H
#define PHOTODELEGATE_H
 
#include <QtGui/QAbstractItemDelegate>
#include <qDebug>
class PhotoDelegate : public QAbstractItemDelegate
{
Q_OBJECT
public:
PhotoDelegate(QObject *parent = 0);
~PhotoDelegate();
 
void paint(
QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const;
 
QSize sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const;
};
 
#endif

我们将定义一个类派生自 QAbstractItemDelegate,用于进行图片的绘制

[edit] photodelegate.cpp

void PhotoDelegate::paint(
QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const
{
qDebug()<<"enter paint";
 
QPen oldPen = painter->pen();
 
QStyle *style = QApplication::style();
 
int margin = style->pixelMetric(QStyle::PM_ButtonMargin);
 
QRect rect = option.rect;
 
if (option.state & QStyle::State_HasFocus) {
painter->fillRect(rect, option.palette.highlight());
 
painter->setPen(option.palette.color(QPalette::HighlightedText));
}
 
rect.adjust(margin, margin, -margin, -margin);
 
QRect decorationRect = rect;
decorationRect.setRight(decorationRect.left() + option.decorationSize.width());
 
QPixmap decoration = qvariant_cast<QPixmap>(index.data(Qt::DecorationRole));
if (!decoration.isNull())
style->drawItemPixmap(painter, decorationRect, Qt::AlignCenter, decoration);
else
painter->drawRect(decorationRect);
 
painter->setPen(oldPen);
}
 
QSize PhotoDelegate::sizeHint(const QStyleOptionViewItem &option, const QModelIndex &) const
{
int margin = QApplication::style()->pixelMetric(QStyle::PM_ButtonMargin);
 
QSize size = option.decorationSize;
 
size.rheight() += 2 * margin;
size.rwidth() += 2 * margin;
 
return size;
}

我们在Paint()函数中绘制从MODEL中获得的数据,这样我们就完成了一个简单图片浏览器

[edit] 代码下载

File:Mediabrowser.zip

[edit] 相关链接

Add categories below. Remove Category:Draft when the page is complete or near complete

This page was last modified on 11 July 2012, at 06:18.
147 page views in the last 30 days.