I'm use QTreeView
to get the images path, then I'm use QListView
to display the images that in specific path as thumbnail.
The problem in the period, create and display the thumbnail images.
The previous process, take a long time to done, depend on the number of images.
And for that reason I decided to use the threads, maybe helps to prevent the hung up which occur in application and increase the speed of create and display the thumbnail images.
void mainWidget::on_treeView_clicked(const QModelIndex &index){
filesModel->clear();
QFileSystemModel *sysModel = qobject_cast<QFileSystemModel*>(ui->treeView->model());
QDir dir(sysModel->filePath(ui->treeView->currentIndex()));
QFileInfoList filesList = dir.entryInfoList(QStringList() << "*.jpg" << "*.jpeg" << "*.tif" << "*.png" << "*.gif" << "*.bmp" ,QDir::Files);
int filesCount = filesList.size();
for(int i=0;i<filesCount;i++){
QPixmap originalImage(filesList[i].filePath());
if(!originalImage.isNull()){
QPixmap scaledImage = originalImage.scaled(150, 120);
filesModel->setItem(i, new QStandardItem(QIcon(scaledImage), filesList[i].baseName()));
}
}
}
How can I use threads with the previous code ?
I believe that a simple and correct approach is using QtConcurrent
as the following:
Note: If you are using Qt 5 you will need to add QT += concurrent
to the .pro file.
Header:
#include <QtCore>
#include <QtGui>
#include <QtWidgets>
#include <QtConcurrent>
namespace Ui {
class MainWindow;
}
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = 0);
~MainWindow();
signals:
void UpdateItem(int, QImage);
private slots:
void on_treeView_clicked(const QModelIndex &);
void List(QFileInfoList filesList, QSize size);
void setThumbs(int index, QImage img);
private:
Ui::MainWindow *ui;
QFileSystemModel *model;
QStandardItemModel *filesmodel;
QFuture<void> thread;
bool running;
};
CPP file:
#include "mainwindow.h"
#include "ui_mainwindow.h"
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
QThreadPool::globalInstance()->setMaxThreadCount(1);
model = new QFileSystemModel(this);
model->setRootPath("\\");
filesmodel = new QStandardItemModel(this);
ui->treeView->setModel(model);
ui->listView->setModel(filesmodel);
connect(this, SIGNAL(UpdateItem(int,QImage)), SLOT(setThumbs(int,QImage)));
ui->treeView->header()->setSectionResizeMode(QHeaderView::ResizeToContents);
running = false;
}
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::on_treeView_clicked(const QModelIndex&)
{
filesmodel->clear();
running = false;
thread.waitForFinished();
QDir dir(model->filePath(ui->treeView->currentIndex()));
QFileInfoList filesList = dir.entryInfoList(QStringList() << "*.jpg" << "*.jpeg" << "*.tif" << "*.png" << "*.gif" << "*.bmp", QDir::Files);
int filesCount = filesList.size();
QPixmap placeholder = QPixmap(ui->listView->iconSize());
placeholder.fill(Qt::gray);
for (int i = 0; i < filesCount; i++)
filesmodel->setItem(i, new QStandardItem(QIcon(placeholder), filesList[i].baseName()));
running = true;
thread = QtConcurrent::run(this, &MainWindow::List, filesList, ui->listView->iconSize());
}
void MainWindow::List(QFileInfoList filesList, QSize size)
{
int filesCount = filesList.size();
for (int i = 0; running && i < filesCount; i++)
{
QImage originalImage(filesList[i].filePath());
if (!originalImage.isNull())
{
QImage scaledImage = originalImage.scaled(size);
if (!running) return;
emit UpdateItem(i, scaledImage);
}
}
}
void MainWindow::setThumbs(int index, QImage img)
{
QIcon icon = QIcon(QPixmap::fromImage(img));
QStandardItem *item = filesmodel->item(index);
filesmodel->setItem(index, new QStandardItem(icon, item->text()));
}
You don't have to use threads to keep your application responsive in this case. Use QCoreApplication::processEvents()
in the loop to keep the application responsive. QCoreApplication::processEvents()
will process all the events in the event queue of the thread which calls it.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With