我如何使用QuaZip提取.zip文件并在QProgressDialog中显示其提取进度?
我已尝试过此question1(以及此question2)的示例但未成功。因为我需要解压缩.zip文件(而不是.gz文件),并且该代码显示了进度百分比但未解压缩文件。 即便如此,我也不知道如何在QProgressDialog中显示%。
我已经能够使用:
提取.zip文件了JlCompress::extractDir("C:/test/test.zip", "C:/test/");
但是,这不是我的目标,因为我需要在QProgressDialog中实时显示提取进度......
这是我的代码:
QString fileName = "C:/test/firefox-29.0.1.gz"; //I need to unzip .zip files
qDebug() << "Opened";
progressUnzip->setWindowTitle(tr("Unzip Manager"));
progressUnzip->setLabelText(tr("Unzipping %1. \nThis can take a long time to complete").arg(fileName));
progressUnzip->setAttribute(Qt::WA_DeleteOnClose);
QFile file(fileName);
file.open(QFile::ReadOnly);
QuaGzipFile gzip;
gzip.open(file.handle(), QuaGzipFile::ReadOnly);
progressUnzip->show();
while(true) {
QByteArray buf = gzip.read(1000);
//process buf
if (buf.isEmpty()) { break; }
QFile temp_file_object;
temp_file_object.open(file.handle(), QFile::ReadOnly);
double progress = 100.0 * temp_file_object.pos() / file.size();
updateUnzipProgress(temp_file_object.pos(), file.size());
qDebug() << qRound(progress) << "%";
}
unzipFinished();
qDebug() << "Finish";
其中:
void MainWindow::updateUnzipProgress(qint64 bytesRead, qint64 totalBytes)
{
qDebug() << bytesRead << "/" << totalBytes;
qint64 th = 1;
if (totalBytes >= 100000000)
{
th = 1000;
}
progressUnzip->setMaximum(totalBytes/th);
progressUnzip->setValue(bytesRead/th);
}
// When unzip finished or canceled, this will be called
void MainWindow::unzipFinished()
{
qDebug() << "Unzip finished.";
progressUnzip->hide();
}
在此代码中,QProgressDialog不显示任何进度条,最后文件未解压缩。
有什么想法吗?
感谢您的帮助,
答案 0 :(得分:4)
我不会为你编写完整的代码,但我可以给你一些提示来帮助你解决问题。
QuaZIP库不提供有关提取进度的任何Qt信号,这意味着您应该自己实现它。
首先,看看JlCompress::extractDir
函数实现,看看它是如何工作的。可以找到源代码here。该函数创建一个QuaZip
对象,描述您要提取的zip存档。然后它迭代存档中的文件。在每次迭代时,它都会创建一个QuaZipFile
对象,该对象描述存档中的压缩文件,然后将其数据写入(=提取)到新文件中。
这是复制功能:
static bool copyData(QIODevice &inFile, QIODevice &outFile)
{
while (!inFile.atEnd()) {
char buf[4096];
qint64 readLen = inFile.read(buf, 4096);
if (readLen <= 0)
return false;
if (outFile.write(buf, readLen) != readLen)
return false;
}
return true;
}
inFile
是压缩的(QuaZipFile
)文件,outFile
是压缩数据被提取到的新文件。
现在您应该了解基础逻辑。
要添加有关提取进度的信号,您可以将JlCompress::extractDir
源代码复制到某个包装类并进行一些更改。
在遍历存档中的文件时,您可以使用QuaZipFile::getFileInfo
获取有关它们的信息。该信息包含未压缩的文件大小。现在返回copyData
函数。您知道已编写了多少字节,并且您知道预期的文件大小。这意味着您可以计算单个文件提取进度。您还可以使用QuaZip::getFileInfoList64
获取总文件数和未压缩的大小。这也可以让你计算整个提取进度。