class TNImageLoadThread: public QThread
{
Q_OBJECT
public:
explicit TNImageLoadThread(const QString &filename, const QSize &targetSize, QObject *parent = Q_NULLPTR);
signals:
void loadFailed(const QString &filename);
void loadFinished(const QString &filename, const QImage &bigImage);
protected:
virtual void run();
private:
const QString m_fileName;
const QSize m_targetSize;
QImage m_targetImage;
QMutex m_mutex;
};
实现文件:
TNImageLoadThread::TNImageLoadThread(const QString &filename, const QSize &targetSize, QObject *parent) :
QThread(parent), m_fileName(filename), m_targetSize(targetSize)
{
}
void TNImageLoadThread::run()
{
QMutexLocker mutexLocker(&m_mutex);
m_targetImage = QImage(m_fileName).scaled(m_targetSize);
if (m_targetImage.isNull())
{
emit loadFailed(m_fileName);
}
else
{
emit loadFinished(m_fileName, m_targetImage);
}
}
调用端代码,可以使用fileName作为ID区分不同的线程返回了指定文件的结果。
QMap<QString, QImage> m_fileNameToImage;
QMap<QString, ImageToolButton*> m_fileNameToButton;
使用信号-槽连接来更新UI控件图片:
m_fileNameToButton[fileName] = imageButton;
QThread *thread = new TNImageLoadThread(fileName, IconSize, this);
connect(thread, SIGNAL(loadFinished(const QString&, const QImage&)), this, SLOT(addThumbnail(const QString&, const QImage&)));
connect(thread, SIGNAL(loadFailed(const QString&)), this, SLOT(showError(const QString&)));
thread->start();
槽函数实现:
void XXXX::addThumbnail(const QString &fileName, const QImage &buttonImage)
{
if (m_fileNameToImage.contains(fileName) && m_fileNameToButton.contains(fileName))
{
m_fileNameToImage[fileName] = buttonImage;
m_fileNameToButton[fileName]->setIcon(QIcon(QPixmap::fromImage(m_fileNameToImage[fileName])));
}
}
void XXXX::showError(const QString &fileName)
{
// 加载显示一张破图?
}