26

I have a code that uses QProcess like this :

int main(int argc, char *argv[])
{
    int status=0;
    QProcess pingProcess;
    QString ba;
    QString exec = "snmpget";
    QStringList params;

    params << "-v"
           << "2c"
           << "-c"
           << "public"
           << "10.18.32.52"
           << ".1.3.6.1.4.1.30966.1.2.1.1.1.5.10";

    status=pingProcess.execute(exec, params);
    
    pingProcess.close();
}

This outputs the following :

SNMPv2-SMI::enterprises.30966.1.2.1.1.1.5.10 = STRING: "0.1"

I want to take(read) this output as QString. I searched for this and I can't find the solution.

Thanks in advance.

sersem1
  • 466
  • 1
  • 4
  • 10

4 Answers4

47

Did you try QByteArray QProcess::readAllStandardOutput() docs - here

QString can be instantiated from QByteArray:

QString output(pingProcess.readAllStandardOutput());

As others mentioned, and I join to them, you should not use execute method and replace it with:

pingProcess.start(exec, params);
pingProcess.waitForFinished(); // sets current thread to sleep and waits for pingProcess end
QString output(pingProcess.readAllStandardOutput());
Azeem
  • 11,148
  • 4
  • 27
  • 40
Shf
  • 3,463
  • 2
  • 26
  • 42
7

In a more Qt way you can try to use readyReadStandardOutput signal:

connect(&pingProcess, SIGNAL(readyReadStandardOutput()), this, SLOT(readData()));

and in corresponding slot readData to the string

QString output = pingProcess.readAllStandardOutput();

ariwez
  • 1,309
  • 17
  • 20
  • 1
    While this is correct, you should be aware that if the process creates a lot of output, you're may receive several calls to the readData slot before the process is finished, so need to handle concatenation of data and still wait on the signal for the process finishing. – TheDarkKnight Jun 27 '13 at 14:22
  • True, connect( &pingProcess, SIGNAL(finished (int)), this, SLOT(handleProcessFinish(int); That way you don't block the flow (in addition waitFofFinished has 30secs default timeout). – ariwez Jun 27 '13 at 14:27
  • Yes, but the 30 seconds is a maximum time to wait. if the process finishes before that, it will return. – TheDarkKnight Jun 27 '13 at 14:30
  • But if it takes more than thirty secs, the output will be unavailable, and that could be hurtful ;) – ariwez Jun 27 '13 at 14:32
  • By default, yes, but you should know what to expect from the process you're calling. Also note that passing -1 for the timeout will ensure that it never does automatically time out, if that is required. I'm not saying this function must be used, but is available for convenience. If the process is very short, such as getting a directory listing, then you'd expect that to be very quick and could wait for it to finish, which allows for less code. – TheDarkKnight Jun 27 '13 at 14:40
  • I'd say: expect the worst case scenario. – ariwez Jun 27 '13 at 14:42
6

@Shf is right in that you should be using readAllStandardOutput. However, you're using the function execute() which is a static method. You should be calling start( ) from an instance of a QProcess.

It may also be a good idea to then either wait for the data with waitForReadyRead, or just wait for the process to finish with waitForFinished( ).

Also, there's an overloaded start function, which allows you to pass the whole command in, which may make your code easier to read: -

QProcess pingProcess;
QString exe = "snmpget -v 2c -c public 10.18.32.52 .1.3.6.1.4.1.30966.1.2.1.1.1.5.10";
pingProcess.start(exe);
pingProcess.waitForFinished();
QString output(pingProcess.readAllOutput());

Note that calling waitForFinished will hang the current process, so if you're going to do something that will take a while, you would then want to dynamically create the QProcess and connect to the finished() signal in order for a connected slot to then read the data.

TheDarkKnight
  • 27,181
  • 6
  • 55
  • 85
1

You shouldn't use QProcess::execute method, it's static and doesn't alter your pingProcess variable. You have no access to a process started using this method. You need to use start() method instead. Note that this method is asynchronous. You need to use waitForFinished and then read the data.

pingProcess.start(exec, params);
pingProcess.waitForFinished();
QByteArray output = pingProcess.readAllStandardOutput();
Pavel Strakhov
  • 39,123
  • 5
  • 88
  • 127