QT多线程实现图片以缩略图形式显示

有时候我们需要把打开的图片以缩略图的形式显示出来,下面是一个小例子,可以作为参考

mainwin.h

#ifndef MAINWIN_H

#define MAINWIN_H

#include <QWidget>
#include <QTimer>
#include <QImage>
class QPushButton;
class QLabel;

class MainWin:public QWidget
{
Q_OBJECT
public:
	MainWin(QWidget*p = NULL, Qt::WindowFlags f = 0);
	~MainWin();
protected slots:
	void openFiles();
	void deleteThread();
	void showError(const QString filename);
	void addThumbnail(QImage);
private:
	void createThumbnail(const QString& filename);
	QWidget* previewwidget;
	int waitseconds;
};

#endif


thumbnailthread.h

#ifndef TNTHREAD_H

#define TNTHREAD_H
#include <QThread>
#include <QImage>
#include <QString>

class ThumbnailThread: public QThread
{
Q_OBJECT
public:
	ThumbnailThread(const QString filename, int n = 1);
	int waitseconds(){return number;};

private:
	void run();
	QImage bigpm, smallpm;
	QString pmfilename;
	int number;

signals:
	void thumbnailFinished(QImage);
	void thumbnailFailed(const QString filename);
};
#endif

 

mainwin.cpp

#include <QDebug>

#include <QLabel>
#include <QPalette>
#include <QLayout>
#include <QFileDialog>
#include <QPushButton>
#include <QMessageBox>
#include "mainwin.h"
#include "thumbnailthread.h"

MainWin::MainWin(QWidget*p, Qt::WindowFlags f)
:QWidget(p,f)
{
	waitseconds = 1;
	QPalette pal = palette();
        pal.setColor(QPalette::Background, Qt::white);
	
	setFixedSize(600,400);
	setWindowTitle("www.cuteqt.com");
	previewwidget = new QWidget(this);	
	previewwidget->setFixedSize(600,350);
	previewwidget->setPalette(pal);
	previewwidget->setAutoFillBackground(true);

	QPushButton* btn = new QPushButton("Open pictures..", this);
	btn->setGeometry(450, 360, 130, 35);
	connect(btn, SIGNAL(clicked()), this, SLOT(openFiles()));

	QGridLayout* layout = new QGridLayout(previewwidget);
}

MainWin::~MainWin()
{
}

void MainWin::openFiles()
{
	waitseconds = 1;//reset

	QStringList list = QFileDialog::getOpenFileNames(this, "Open one or more pictures", "", "*.jpg *.png *.bmp");
	if( list.count() == 0)
	{
		return;
	}

	//open files one by one, and create thread to create thumbnail for each file
	QStringList::Iterator it = list.begin();
	while(it != list.end()) 
	{
     		createThumbnail(*it);
     		++it;
 	}
}

void MainWin::createThumbnail(const QString& filename)
{
	qDebug() << filename;
	QThread* thread = new ThumbnailThread(filename, 10 - waitseconds);
	waitseconds ++;
	connect(thread, SIGNAL(thumbnailFinished(QImage)), this, SLOT(addThumbnail(QImage)));
	connect(thread, SIGNAL(thumbnailFailed(const QString)), this, SLOT(showError(const QString)));
	connect(thread, SIGNAL(finished()), this, SLOT(deleteThread()));
	thread->start();
}

void MainWin::deleteThread()
{
	QObject* obj = sender();
	ThumbnailThread * th = qobject_cast<ThumbnailThread*>(obj);
	qDebug() << "delete thread..." << th->waitseconds();
	obj->deleteLater();
}

void MainWin::addThumbnail(QImage smallpm)
{
	static int i = 0;
	static int j = 0;

        qWarning() << "thumbnail create successfully..." << j << i ;
	qWarning() << "Small PM:" << smallpm << smallpm.size();
	QLabel* label = new QLabel;
	label->setPixmap(QPixmap::fromImage(smallpm));
	QGridLayout* gl = qobject_cast<QGridLayout*>(previewwidget->layout());
        gl->addWidget(label, j, i);
	label->show();
	qWarning() << "Label:" <<label << label->isVisible();
	i++;
	if( i > previewwidget->width() / smallpm.width()) 
	{
		i = 0;
		j ++;
	}
}

void MainWin::showError(const QString filename)
{
	QMessageBox::information(this, "Error!", filename+" is not a valid picture file.");
}

 

thumbnailthread.cpp

#include <QDebug>

#include "thumbnailthread.h"

const int TN_WIDTH=160;
const int TN_HEIGHT=120;

ThumbnailThread::ThumbnailThread(const QString filename, int n)
{
	pmfilename = filename;
	bigpm = QImage(filename);
	number = n;
}

void ThumbnailThread::run()
{
	if( bigpm.isNull())
	{
		emit thumbnailFailed(pmfilename);
	}
	else
	{
		qWarning() << "thread start..." << number;
		sleep(number);
		smallpm = bigpm.scaled(TN_WIDTH, TN_HEIGHT, Qt::KeepAspectRatio);
		emit thumbnailFinished(smallpm);
	}
}

 

main.cpp

#include <QApplication>

#include "mainwin.h"

int main(int argc, char* argv[])
{
	QApplication app(argc, argv);
	MainWin mw;
	mw.show();
	return app.exec();
}

 

实现结果如下:

 

 

如果需要整个工程可以留言,与大家分享

发布了90 篇原创文章 · 获赞 89 · 访问量 40万+
展开阅读全文

没有更多推荐了,返回首页

©️2019 CSDN 皮肤主题: 大白 设计师: CSDN官方博客

分享到微信朋友圈

×

扫一扫,手机浏览