Question

I'm trying to execute the function "gzip -c file.bin > file.zip" in Linux. This works fine on the command line but I need to call it from my application using Qt 4.8.2. If I try:

QProcess *pProc = QProcess(this);
connect(pProc, SIGNAL(finished(int, QProcess::ExitStatus)), this, SLOT(onFinished(int, QProcess::ExitStatus)));
pProc->start("gzip -c file.bin > file.zip");

Then onFinished() reports an exitCode of 1. I've tried:

pProc->start("gzip", QStringList << "-c" << "file.bin" << ">" << "file.zip");

or using startDetached() instead but I can't find a combination that works.

Was it helpful?

Solution 2

I followed vahancho's suggestion of using QProcess::setStandardOutputFile() and it works fine. The code is:

#include <QObject>
#include <QString>

class TestZip : public QObject
{
    Q_OBJECT

public:
    TestZip(const QString file, const QString zip);

private slots:
    void onZipReadyReadStandardOutput();
    void onZipReadyReadStandardError();
    void onZipFinished(int exitCode, QProcess::ExitStatus exitStatus);

private:
    QProcess *_pZip;
};


#include <QFileInfo>


TestZip::TestZip(const QString file, const QString zip)
{
    QFileInfo fileInfoZip(zip);

    _pZip = new QProcess(this);

    QString cmd = QString("gzip -c %1").arg(file);
    _pZip->setStandardOutputFile(fileInfoZip.filePath());

    Connect(_pZip, SIGNAL(finished(int, QProcess::ExitStatus)), this, SLOT(onZipFinished(int, QProcess::ExitStatus)));
    Connect(_pZip, SIGNAL(readyReadStandardOutput()), this, SLOT(onZipReadyReadStandardOutput()));
    Connect(_pZip, SIGNAL(readyReadStandardError()), this, SLOT(onZipReadyReadStandardError()));

    _pZip->start(cmd);
    if (!_pZip->waitForStarted())
    {
        qDebug() << "Zip failed to start: " << cmd;
        _pZip->deleteLater();
        _pZip = NULL;
    }
}


void TestZip::onZipReadyReadStandardOutput()
{
    qDebug() << __FUNCTION__ << _pZip->readAllStandardOutput();
}


void TestZip::onZipReadyReadStandardError()
{
    qDebug() << __FUNCTION__ << _pZip->readAllStandardError();
}


void TestZip::onZipFinished(int exitCode, QProcess::ExitStatus exitStatus)
{
    qDebug() << __FUNCTION__ << "(" << exitCode << ", " << exitStatus << ")";

    _pZip->deleteLater();
    _pZip = NULL;
}

OTHER TIPS

The problem with this: pProc->start("gzip -c file.bin > file.zip"); is that QProcess interprets each item in the string, after the command, as an argument to be passed to the command. Therefore, it will pass items that gzip doesn't understand, such as '>'.

What you need to do is either handle the redirection separately, or alter how the command is called. You could try something like this: -

pProc->start("bash -c \"gzip -c file.bin > file.zip\"");

Bash can take a command string as an input, with the -c argument, so we wrap the string in quotes and pass that to the bash interpreter.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top