Как скопировать файлы из одной директории в другую,используя QProgressDialog и QtConcurrent?

Нужно скопировать файлы из одной директории в другую используя QProgressDialog и QtConcurrent. Здесь я задавал подобный вопрос,но используя QProgressBar в основном окне: Как скопировать файлы и папки из одной директории в другую и отображать процесс копирования в QProgressBar?

Там отображается процесс копирования каждого файла в процентах. Мне же нужно,чтобы показывался процесс в процентах до окончания операции копирования файлов(а не каждого файла).

Пример:

И сделать так чтобы вместо текста(converting contact details),отображалось имя копируемого файла в данный момент.


Ответы (1 шт):

Автор решения: ramdolpix

Не стал использовать QtConcurrent,использовал QThread.

CopyFiles.h:

#include <QThread>
#include <QFile>
#include <QDir>

class CopyFiles : public QThread
{
    Q_OBJECT

public:
    CopyFiles(QString source,
               QString destanation,
               QObject *parent = 0)
        : QThread(parent)
        , sourcePath(source)
        , destanationPath(destanation)
    {}

    void run()
    {
        getListFilesForCopy(sourcePath,destanationPath,sourceFiles,destanationFiles);
        pathCreate(sourcePath,destanationPath);

        emit filesListSize(0,sourceFiles.length()); //sends numbers of files
        int currentProgressState = 1;
        for(int i = 0; i < sourceFiles.size(); ++i)
        {
            copyFile(sourceFiles.at(i),destanationFiles.at(i));
            emit updateProgress(currentProgressState++);  //update state
        }        
    }
    void pathCreate(QString src, QString dst)
    {
        QDir dir(src);

        foreach (QString d, dir.entryList(QDir::Dirs | QDir::NoDotAndDotDot)) {
            QString dst_path = dst + QDir::separator() + d;
            dir.mkpath(dst_path);
            pathCreate(src+ QDir::separator() + d, dst_path);
        }
    }
    void getListFilesForCopy(QString src, QString dst,QStringList &srcListFiles,QStringList &dstListFiles)
    {
        QDir dir(src);

        foreach (QString d, dir.entryList(QDir::Dirs | QDir::NoDotAndDotDot)) {
            QString dst_path = dst + QDir::separator() + d;
            getListFilesForCopy(src+ QDir::separator() + d, dst_path,srcListFiles,dstListFiles);
        }

        QStringList list = dir.entryList(QDir::Files);
        foreach (QString f, list) {
            QString sourceDir = src + QDir::separator() + f;
            QString destDir = dst + QDir::separator() + f;
            srcListFiles.append(sourceDir);
            dstListFiles.append(destDir);
        }
    }
signals:
    void updateProgress(int i);
    void filesListSize(int zero,int size);
private:
    QString sourcePath,destanationPath;
    QStringList sourceFiles,destanationFiles;

    void copyFile(QString srcFile, QString dstFile)
    {
        QFile::copy(srcFile, dstFile);
    }
};

CopyQProgressDialog.cpp:

#include "CopyQProgressDialog.h"

CopyQProgressDialog::CopyQProgressDialog(QString source, QString dest, QObject *parent) :
    QObject(parent)
{
    progressDialog = new QProgressDialog("Copying...", "Cancel", 0, 0);
    copyFiles = new CopyFiles(source,dest,this);

    connect(copyFiles,SIGNAL(filesListSize(int,int)),progressDialog,SLOT(setRange(int,int)));
    connect(copyFiles,SIGNAL(updateProgress(int)),progressDialog,SLOT(setValue(int)));
    copyFiles->start();
    
    connect(progressDialog, SIGNAL(canceled()), this, SLOT(cancel()));
    timer = new QTimer(this);
    connect(timer, SIGNAL(timeout()), this, SLOT(running()));
    timer->start(0);
}

void CopyQProgressDialog::running()
{
    if (progressDialog->maximum())
        timer->stop();
}

void CopyQProgressDialog::cancel()
{
    timer->stop();
    copyFiles->terminate();
}

CopyQProgressDialog.h:

#include "CopyFiles.h"

#include <QObject>
#include <QProgressDialog>
#include <QTimer>

class CopyQProgressDialog : public QObject
{
    Q_OBJECT
public:
    CopyQProgressDialog(QString source,QString dest,QObject *parent = 0);
public slots:
    void running();
    void cancel();
private:
    CopyFiles *copyFiles;
    QProgressDialog *progressDialog;
    QTimer *timer;

};

MainWindow.cpp:

void MainWindow::on_pushButton_clicked()
{
    CopyQProgressDialog *cpd = new CopyQProgressDialog("/folder1","/folder2",this);
}

Для обычного QProgressBar достаточно CopyFiles.h:

void MainWindow::on_pushButton_clicked(){
    QProgressBar *pb = ui->progressBar;
    CopyFiles *cp = new CopyFiles("/folder1","/folder2",this);
    
    connect(cp,SIGNAL(filesListSize(int,int)),pb,SLOT(setRange(int,int)));
    connect(cp,SIGNAL(updateProgress(int)),pb,SLOT(setValue(int)));
    cp->start();
}
→ Ссылка