首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >使用7zip作为子进程提取文件的QProcess

使用7zip作为子进程提取文件的QProcess
EN

Stack Overflow用户
提问于 2022-04-27 21:37:38
回答 2查看 247关注 0票数 0

在使用C++和Qt的应用程序中(在windows 10上),我有一个用例。应用程序使用7zip.exe作为子进程来解压缩选定文件夹中的文件。我需要使用QProcess来提取文件。

我想出的代码如下所示。

代码语言:javascript
运行
复制
     MainWindow.h
QStringList zipFiles;

MainWindow.cpp

代码语言:javascript
运行
复制
void MainWindow::on_browseButton_clicked()
{
        directory = QFileDialog::getExistingDirectory(this);
        if(recursiveOperation){
            QDirIterator it(directory.canonicalPath(), QStringList() << "*.zip" <<  "*.7z", QDir::Files, QDirIterator::Subdirectories);
             ui->outputLogResultList->addItem("File selected to uncompress");
             ui->outputLogResultList->addItem("-----------------------------");
            while (it.hasNext()){
                QString file = it.next();
                ui->outputLogResultList->addItem(file);
                zipFilesWithRecursion.append(file);
            }

        }else{
            zipFilesWithoutRecursion = directory.entryList(QStringList() << "*.zip"<< "*.7z", QDir::Files);
            qDebug() << zipFilesWithoutRecursion;

            foreach(QString filename4, zipFilesWithoutRecursion) {
                     qDebug() << "inside loop";
                    zipFilesWithCompletePath.append( QString(directory.canonicalPath()+"/%1").arg(filename4));
                }



                qDebug() << "without recursion";
                qDebug() << zipFilesWithCompletePath;
        }
}



void MainWindow::unZipFile()
{
    int numberOfFiles;
    if(recursiveOperation){
        numberOfFiles = zipFilesWithRecursion.size();
        foreach(QString filename3, zipFilesWithRecursion) {
            QStringList queryArguments;
            queryArguments << "x";
                  qDebug() << filename3;
                  queryArguments <<""""+ filename3+ """";
                  queryArguments << "-o"+directory.canonicalPath()+"/output"+QString().setNum(numberOfFiles);
                  qDebug() << queryArguments;
                  unZip.setWorkingDirectory(QCoreApplication::applicationDirPath());
                  unZip.start("7za.exe", queryArguments);
                  numberOfFiles--;
              }
        numberOfFiles = 0;
    }else{
        numberOfFiles = zipFilesWithCompletePath.size();
        foreach(QString filename3, zipFilesWithCompletePath) {
            QStringList queryArguments;
            queryArguments << "x";
                  qDebug() << filename3;
                  queryArguments <<""""+ filename3+ """";
                  queryArguments << "-o"+directory.canonicalPath()+"/output"+QString().setNum(numberOfFiles);
                  qDebug() << queryArguments;
                  unZip.setWorkingDirectory(QCoreApplication::applicationDirPath());
                  unZip.start("7za.exe", queryArguments);
                  numberOfFiles--;
              }
        numberOfFiles = 0;
    }


}

代码正确运行,但在处理第一个文件后,它不处理任何其他文件,并显示状态"QProcess::start: process已经在运行“输出段如下。

代码语言:javascript
运行
复制
Warning: QT_DEVICE_PIXEL_RATIO is deprecated. Instead use:
   QT_AUTO_SCREEN_SCALE_FACTOR to enable platform plugin controlled per-screen factors.
   QT_SCREEN_SCALE_FACTORS to set per-screen DPI.
   QT_SCALE_FACTOR to set the application global scale factor.
("SemiFinal.zip", "temata_vskp_-_podklady_pro_zadani_vskp(10).zip")
inside loop
inside loop
without recursion
("F:/taskPractiseDirectoryForQt/SemiFinal.zip", "F:/taskPractiseDirectoryForQt/temata_vskp_-_podklady_pro_zadani_vskp(10).zip")
"F:/taskPractiseDirectoryForQt/SemiFinal.zip"
("x", "F:/taskPractiseDirectoryForQt/SemiFinal.zip", "-oF:/taskPractiseDirectoryForQt/output2")
"F:/taskPractiseDirectoryForQt/temata_vskp_-_podklady_pro_zadani_vskp(10).zip"
("x", "F:/taskPractiseDirectoryForQt/temata_vskp_-_podklady_pro_zadani_vskp(10).zip", "-oF:/taskPractiseDirectoryForQt/output1")
QProcess::start: Process is already running

这个文件夹有两个.zip文件,我的问题是为什么第二个文件没有被处理。

EN

Stack Overflow用户

回答已采纳

发布于 2022-04-28 09:01:47

您必须等待您的QProcess (unZip)完成,然后再处理下一个文件,或者在void MainWindow::unZipFile()方法中循环foreach(QString filename3, zipFilesWithCompletePath)中的每个文件中创建QProcess实例,以便并发处理它们。如果您尝试等待unZip.waitForFinished(),您的应用程序将在这段时间内没有响应,因为它的主线程将被挂起直到进程完成。如果希望并发处理文件,则应该在堆中创建QProcess实例,例如,auto unZipFileProcess = new QProcess(this);,您需要编写一些代码来控制已启动的进程,并等待它们全部完成,然后才能关闭应用程序,因为在这种情况下,所有进程都会被它们的析构函数中断和终止。要控制进程状态,应该连接到QProcess实例信号-- errorOccurredfinished。此外,这些信号应该连接到QProcess的deleteLater插槽,以避免内存增长。此时,您根本不需要unZip静态变量或成员变量(我不知道它是如何声明的)。以另一种方式,如果您不需要跟踪文件处理(等待完成、报告进程错误等等),则可以以与静态QProcess::startDetached方法分离的方式启动进程,而根本不创建任何QProcess实例。因此,您不需要控制它们并将它们与应用程序生命周期同步。您需要重新设计您的MainWindow::unZipFile()方法,以避免代码重复。

票数 1
EN
查看全部 2 条回答
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/72035578

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档