3
votes

I am trying to create a progress bar for a file copy in Qt. This is as close as I could find, however I believe this doesn't work because according to the Qt class documentation:

Unlike other QIODevice implementations, such as QTcpSocket, QFile does not emit the aboutToClose(), bytesWritten(), or readyRead() signals. This implementation detail means that QFile is not suitable for reading and writing certain types of files, such as device files on Unix platforms.

How can I do something like this? I don't know how to implement my own signals.

Here is my code:

void Replicator::anotbaandbFile(QDir source, QDir target)
{
    source.setFilter(QDir::Files | QDir::NoDotAndDotDot | QDir::NoSymLinks);
    target.setFilter(QDir::Files | QDir::NoDotAndDotDot | QDir::NoSymLinks);

    qDebug() << "Scanning: " << source.path();

    QStringList sourceFileList = source.entryList();
    QStringList targetFileList = target.entryList();
    for (int aCount = 0; aCount < sourceFileList.count(); aCount++)
    {
        bool found = false;
        for (int bCount = 0; bCount < targetFileList.count(); bCount++)
            if (sourceFileList.at(aCount) == targetFileList.at(bCount))
                found = true;
        if (found == false)
        {

            sourceFile = new QFile(source.absolutePath()+"/"+sourceFileList.at(aCount));
            targetFile = new QFile(target.absolutePath()+"/"+sourceFileList.at(aCount));
            progressBar->setMinimum(0);
            progressBar->setMaximum(sourceFile->size());
            written = 0;
            connect(sourceFile,SIGNAL(bytesWritten(qint64)),SLOT(onWrite(qint64)));
            sourceFile->copy(targetFile->fileName());
            //QFile::copy(source.absolutePath()+"/"+sourceFileList.at(aCount), target.absolutePath()+"/"+sourceFileList.at(aCount));
            qDebug() << source.absolutePath()+"/"+sourceFileList.at(aCount) << " " << target.absolutePath()+"/"+sourceFileList.at(aCount);
        }
    }
}

and

void Replicator::onWrite(qint64 w)
{
    written += w;
    progressBar->setValue( written );
}
2

2 Answers

2
votes

new code modified from above

if (found == false)
        {
            sourceFile = new QFile(source.absolutePath()+"/"+sourceFileList.at(aCount));
            targetFile = new QFile(target.absolutePath()+"/"+sourceFileList.at(aCount));
            progressBar->setMinimum(0);
            progressBar->setMaximum(sourceFile->size());
            QByteArray buffer;
            for (int count = 0; !(buffer = sourceFile->read(1000000)).isEmpty(); count+=1000000)
            {
                targetFile->write(buffer);
                progressBar->setValue(count);
            }
            //targetFile->write(buffer);
            //QFile::copy(source.absolutePath()+"/"+sourceFileList.at(aCount), target.absolutePath()+"/"+sourceFileList.at(aCount));
            qDebug() << "copying " << sourceFile->fileName() << " to " << targetFile->fileName();
        }
1
votes

You can simply copy large files by portions of fixed size, than count portions already copied and callculate of percentage of work by dividing it to overal count of portions.

int iWorkPercentage = (int)(((float)iPortionsProcessed / (float)iOveralPortions) * 100);