Lykurg
12th August 2010, 10:30
Hi,
this is the task: Scan a folder recursive for - lets say - png files and give their addresses back in a QStringList. Furthermore the count of the found images should be displayed in a label or whatever during the scan. And of course the gui is not allowed to freeze and you should be able to abort the scan.
And the solution is ... ? Or better asked, what is the best, easiest and best-performance solution?
Right now I have a simple subclasses thread and do like:
class ThreadReadDir : public QThread
{
Q_OBJECT
public:
explicit ThreadReadDir(QObject* parent = 0)
: QThread(parent)
{
m_stopped = false;
}
void stop()
{
m_stopped = true;
}
void readDir(QDir dir)
{
m_dir = dir;
if (!m_stopped)
start();
}
void run()
{
readDir_private(m_dir);
}
QStringList files() const
{
return m_files;
}
Q_SIGNALS:
void currentFileCountChanged(int);
private:
QStringList m_files;
QDir m_dir;
bool m_stopped;
void readDir_private(QDir dir)
{
if (m_stopped)
return;
QStringList files = dir.entryList(QStringList() << "*.png", QDir::Files, QDir::Name);
for (int i = 0; i < files.count(); ++i)
m_files << dir.absolutePath() + QDir::separator() + files.value(i);
Q_EMIT currentFileCountChanged(m_files.count());
if (m_stopped)
return;
QStringList directories = dir.entryList(QStringList(), QDir::AllDirs | QDir::NoDotAndDotDot, QDir::Name);
for (int i = 0; i < directories.count(); ++i)
{
if (m_stopped)
return;
readDir_private(dir.absolutePath() + QDir::separator() + directories.at(i));
}
}
};With
// Constructor
ThreadReadDir* m_filethread = new ThreadReadDir(this);
QObject::connect(m_filethread, SIGNAL(currentFileCountChanged(int)), this, SLOT(setFileCount(int)));
// After scan request
m_filethread->readDir(QDir(/*...*/));
//
void XXX::setFileCount(int cnt)
{
ui->statRead->setText(QString("%1 Files").arg(cnt));
}
//
void XXX::OnAbortRequest()
{
m_filethread->stop();
m_filethread->wait();
}
It works, but it is a hell of work for such a simple request and therefore I wonder if there is a easier and better to maintain way to achieve that. QtConcurrent::run would be fine if one could cancel it.
Thanks for sharing your thoughts,
Lykurg
this is the task: Scan a folder recursive for - lets say - png files and give their addresses back in a QStringList. Furthermore the count of the found images should be displayed in a label or whatever during the scan. And of course the gui is not allowed to freeze and you should be able to abort the scan.
And the solution is ... ? Or better asked, what is the best, easiest and best-performance solution?
Right now I have a simple subclasses thread and do like:
class ThreadReadDir : public QThread
{
Q_OBJECT
public:
explicit ThreadReadDir(QObject* parent = 0)
: QThread(parent)
{
m_stopped = false;
}
void stop()
{
m_stopped = true;
}
void readDir(QDir dir)
{
m_dir = dir;
if (!m_stopped)
start();
}
void run()
{
readDir_private(m_dir);
}
QStringList files() const
{
return m_files;
}
Q_SIGNALS:
void currentFileCountChanged(int);
private:
QStringList m_files;
QDir m_dir;
bool m_stopped;
void readDir_private(QDir dir)
{
if (m_stopped)
return;
QStringList files = dir.entryList(QStringList() << "*.png", QDir::Files, QDir::Name);
for (int i = 0; i < files.count(); ++i)
m_files << dir.absolutePath() + QDir::separator() + files.value(i);
Q_EMIT currentFileCountChanged(m_files.count());
if (m_stopped)
return;
QStringList directories = dir.entryList(QStringList(), QDir::AllDirs | QDir::NoDotAndDotDot, QDir::Name);
for (int i = 0; i < directories.count(); ++i)
{
if (m_stopped)
return;
readDir_private(dir.absolutePath() + QDir::separator() + directories.at(i));
}
}
};With
// Constructor
ThreadReadDir* m_filethread = new ThreadReadDir(this);
QObject::connect(m_filethread, SIGNAL(currentFileCountChanged(int)), this, SLOT(setFileCount(int)));
// After scan request
m_filethread->readDir(QDir(/*...*/));
//
void XXX::setFileCount(int cnt)
{
ui->statRead->setText(QString("%1 Files").arg(cnt));
}
//
void XXX::OnAbortRequest()
{
m_filethread->stop();
m_filethread->wait();
}
It works, but it is a hell of work for such a simple request and therefore I wonder if there is a easier and better to maintain way to achieve that. QtConcurrent::run would be fine if one could cancel it.
Thanks for sharing your thoughts,
Lykurg