read data continuously from QProcess
-
I want to read the continuous data from QProcess.
The problem is that I can not read continuously the compressing progress of 7z.exe, but can only get the final result after the process is finished. It seems that the signal of "readyReadStandardOutput" will be emitted only once when QProcess is finished.
My code logic is below
- make an instance of QProcess : QProcess proc
- set readChannel : proc.setReadChannel(QProcess::StandardOutput)
- connect signal and slots:
. connect( &proc, &QProcess::readyReadStandardOutput,[&](){
qDebug()<<QString::fromLocal8bit(proc.readAllStandardOutput());
}
.connect(&proc,&QProcess::finished,[&](){
qDebug()<<"Process finished";
} - set program start the Process:
.proc.setProgram("cmd.exe")
.proc.startCommand("7z.exe a myfolder.zip myfolder")
.proc.waitForFinished(-1)
.proc.close();
@jgxy1123
Having written earlier what you need to try to see whether you can get output from7zip
successfully.Just a heads up: rather than running an external command (you/end-users need
7z.exe
installed, and code only works under Windows) you might consider doing the "zipping" directly in your Qt code. zlib is a library written in C that many people use. See also e.g. https://forum.qt.io/topic/74306/how-to-manage-zip-file.Though your example passes a directory/folder to zip, this can absolutely be done but does require a lot more work than just zipping one file/stream. See e.g. https://github.com/sebastiandev/zipper.
May not apply to you (you may want simplicity of just running
7z.exe
command) but here for others reading this. -
Here's how I parse the output of 7zip and send it to a progress bar object:
// 7z a -bso0 -bsp1 <destination> <f1> <f2> <f3> auto cmd = m_7ZipCommand + "a -bso0 -bsp1 " + destFile + " " + Folder1+ " " + Folder2 + " " + Folder3; ... // connect the QProcess finished signal connect(&m_zipProcess, QOverload<int, QProcess::ExitStatus>::of(&QProcess::finished), this, &ProjectionExporter::onExportFinished); ... // Parse the output reported by 7Zip to report the progress percentage connect(&m_zipProcess, &QProcess::readyRead, this, [this]() { QString output = m_zipProcess.readAllStandardOutput(); QRegularExpression percentageMessage("^(\\s*)(\\d+)(%.*)$"); QRegularExpressionMatch match = percentageMessage.match(output); if (match.hasMatch()) { const int percentageExported = match.captured(2).toInt(); const float percentAsFloat = static_cast<float>(percentageExported) / 100.0f; m_exportProgress.complatedFiles = static_cast<int>(static_cast<float>(m_filesToBeExported) * percentAsFloat); m_exportProgress.progressInPercentage = percentageExported; emit exportProgress(m_exportProgress); } });
-
Here's how I parse the output of 7zip and send it to a progress bar object:
// 7z a -bso0 -bsp1 <destination> <f1> <f2> <f3> auto cmd = m_7ZipCommand + "a -bso0 -bsp1 " + destFile + " " + Folder1+ " " + Folder2 + " " + Folder3; ... // connect the QProcess finished signal connect(&m_zipProcess, QOverload<int, QProcess::ExitStatus>::of(&QProcess::finished), this, &ProjectionExporter::onExportFinished); ... // Parse the output reported by 7Zip to report the progress percentage connect(&m_zipProcess, &QProcess::readyRead, this, [this]() { QString output = m_zipProcess.readAllStandardOutput(); QRegularExpression percentageMessage("^(\\s*)(\\d+)(%.*)$"); QRegularExpressionMatch match = percentageMessage.match(output); if (match.hasMatch()) { const int percentageExported = match.captured(2).toInt(); const float percentAsFloat = static_cast<float>(percentageExported) / 100.0f; m_exportProgress.complatedFiles = static_cast<int>(static_cast<float>(m_filesToBeExported) * percentAsFloat); m_exportProgress.progressInPercentage = percentageExported; emit exportProgress(m_exportProgress); } });
@mranger90 said in read data continuously from QProcess:
connect(&m_zipProcess, &QProcess::readyRead, this, this {
So, is the slot called?
-
Here's how I parse the output of 7zip and send it to a progress bar object:
// 7z a -bso0 -bsp1 <destination> <f1> <f2> <f3> auto cmd = m_7ZipCommand + "a -bso0 -bsp1 " + destFile + " " + Folder1+ " " + Folder2 + " " + Folder3; ... // connect the QProcess finished signal connect(&m_zipProcess, QOverload<int, QProcess::ExitStatus>::of(&QProcess::finished), this, &ProjectionExporter::onExportFinished); ... // Parse the output reported by 7Zip to report the progress percentage connect(&m_zipProcess, &QProcess::readyRead, this, [this]() { QString output = m_zipProcess.readAllStandardOutput(); QRegularExpression percentageMessage("^(\\s*)(\\d+)(%.*)$"); QRegularExpressionMatch match = percentageMessage.match(output); if (match.hasMatch()) { const int percentageExported = match.captured(2).toInt(); const float percentAsFloat = static_cast<float>(percentageExported) / 100.0f; m_exportProgress.complatedFiles = static_cast<int>(static_cast<float>(m_filesToBeExported) * percentAsFloat); m_exportProgress.progressInPercentage = percentageExported; emit exportProgress(m_exportProgress); } });
@mranger90
Looks much like you said originally. Does it get the output to parse? If not, have you acted on the suggestions to your issue?It would be "odd" to connect slot
&QProcess::readyRead
with code which only callsreadAllStandardOutput()
. -
@mranger90 said in read data continuously from QProcess:
connect(&m_zipProcess, &QProcess::readyRead, this, this {
So, is the slot called?
-
@jsulm
Yes, this slot gets called regularly. It's how I update a progress bar for the operator.@mranger90
So are you saying it is resolved and you get what you want, or do you still have any issue? -
@mranger90
So are you saying it is resolved and you get what you want, or do you still have any issue? -
@jsulm
Yes, this slot gets called regularly. It's how I update a progress bar for the operator.@mranger90 If it is called did you check what "output" is? Maybe your regexp is wrong...
-
@mranger90 LOL, I'm sorry :)
-
@mranger90 said in read data continuously from QProcess:
I'm not the one with the issue
Oh, I also did not realise :-D