在使用C++和Qt的应用程序中(在windows 10上),我有一个用例。应用程序使用7zip.exe作为子进程来解压缩选定文件夹中的文件。我需要使用QProcess来提取文件。
我想出的代码如下所示。
MainWindow.h
QStringList zipFiles;
MainWindow.cpp
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已经在运行“输出段如下。
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文件,我的问题是为什么第二个文件没有被处理。
发布于 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实例信号-- errorOccurred
和finished
。此外,这些信号应该连接到QProcess的deleteLater
插槽,以避免内存增长。此时,您根本不需要unZip
静态变量或成员变量(我不知道它是如何声明的)。以另一种方式,如果您不需要跟踪文件处理(等待完成、报告进程错误等等),则可以以与静态QProcess::startDetached
方法分离的方式启动进程,而根本不创建任何QProcess实例。因此,您不需要控制它们并将它们与应用程序生命周期同步。您需要重新设计您的MainWindow::unZipFile()
方法,以避免代码重复。
https://stackoverflow.com/questions/72035578
复制相似问题