PDA

Visualizza la versione completa : [C++/QT] Standard output redirection


fermat
09-02-2013, 14:25
salve!
in un mio progetto Qt ho creato una classe per lanciare un comando tramite QProcess.
questa è la funzione:


QString ExecCommand::execCmd()
{
QByteArray result = p.readAll();
p.start("ls", QStringList() << "-l" << "/home/matte");
p.write(result);
p.closeWriteChannel();
if (!p.waitForFinished()) {
exit(0);
}
qDebug("Result: %s", p.readAll().data());
return p.readAll().data();
}

questo output lo vorrei mettere su una QPlainTextEdit.
alla pressione di un bottone ho fatto così:


ExecCommand ec;
ui->txtResult->appendPlainText(ec.execCmd());

qDebug mi fa vedere l'output, e quindi il comando funziona.
ma non viene riempita la textedit.
suppongo mi manchi qualcosa.
una dritta??

MItaly
09-02-2013, 14:53
QProcess eredita la readAll da QIODevice, per cui, come accade per ogni stream di input, una volta che hai già letto tutto l'input, chiamare nuovamente la readAll non può dare esito positivo (a meno di non fare una seek ad inizio file, cosa che non credo sia possibile con lo standard output di un processo).
In altre parole, ti "bruci" la chance di leggere l'output del programma nella qDebug. Per ovviare al problema, prima costruisci una stringa contenente l'output che ti interessa:


QString out(p.readAll());

e poi usala per il debug (se necessario) e come stringa da restituire:


qDebug("Result: %s", out);
return out;


Per inciso, aggiungo il tag C++ al titolo, dato che le Qt si possono usare da più linguaggi.

fermat
09-02-2013, 20:01
perfetto così funziona alla perfezione!!
grazie!!

MItaly
10-02-2013, 02:38
:ciauz:

fermat
10-02-2013, 11:32
pensavo di aver risolto, e invece neanche per niente.


QString ExecCommand::execCmd(QString url)
{
QByteArray result = p.readAll();
//p.start("youtube-dl", QStringList() << "-x" << "--audio-format" << " mp3" << url);
p.start("youtube-dl", QStringList() << "-x" << url);
p.write(result);
p.closeWriteChannel();
if (!p.waitForFinished()) {
qDebug("%s", "NO");
}
QString strOut(p.readAll());
return strOut;
}

l'operazione che viene eseguita è abbastanza lunga, e succede che parte e poi a un certo si ferma.
il programma in verità rimane attivo, però il comando si interrompe.
e non ci sono errori in output.

MItaly
10-02-2013, 13:57
Il programma in questione scrive in output grandi quantità di testo?

fermat
10-02-2013, 14:57
bhe dipende cosa che intendi per grandi quantità.
diciamo che il programma in questione da in tempo rale la situazione delle operazioni.
quindi le righe che scrive solo poche (circa una ventina) solo che in tempo reale da la situazione su percentuale, tempo, ecc....

quindi da questo punto di vista forse si, da un bel pò di output.

MItaly
10-02-2013, 21:17
Il dubbio che mi viene è che, se il programma genera tanto output e tu lo vuoi leggere solo alla fine, rapidamente si riempie il buffer della pipe, e il programma si blocca attendendo che questo venga svuotato... prova a leggere l'output un po' alla volta (in un ciclo) invece che tutto alla fine.

fermat
10-02-2013, 22:17
si penso tu abbia ragione.
oggi pomeriggio ho provato qualcosa del genere ma senza successo:


QString ExecCommand::execCmd(QString url)
{
p.start("youtube-dl", QStringList() << "-x" << url);
p.waitForFinished();
QString line;
QTextStream reader(p.readAllStandardOutput());
QString result;
while((line = reader.readAll()) != NULL)
{
result.append(line);
}

return result;
}

così facendo ottengo lo stesso risultato.

MItaly
11-02-2013, 03:01
Aspé, forse la situazione è molto più semplice del previsto:


QString ExecCommand::execCmd(QString url)
{
QByteArray result = p.readAll();
//p.start("youtube-dl", QStringList() << "-x" << "--audio-format" << " mp3" << url);
p.start("youtube-dl", QStringList() << "-x" << url);
p.write(result);
p.closeWriteChannel();
QString strOut(p.readAll());
if (!p.waitForFinished()) {
qDebug("%s", "NO");
}
return strOut;
}
ovvero, prima leggi tutto (lasciando che siano le Qt ad occuparsi di svuotare la pipe man mano), poi aspetta il termine del programma (che peraltro dovrebbe essere già arrivato)

Loading