2010-11-14 9 views
0

Je dois appeler un exécutable, à partir de mon application QT, surveiller la sortie, puis afficher la sortie dans un navigateur de texte. L'exécutable que j'appelle de mon application QT fonctionnera pendant de nombreuses heures (~ 12) et chaque fois que l'exécutable crache quelque chose sur stdout, j'ai besoin d'analyser la sortie pour pouvoir suivre sa progression, puis l'afficher à l'écran.Je ne peux pas mettre stdout à mettre à jour dans Qt

Je l'ai fait ci-dessous pour commencer ... ce qui est un début ... Mais il affiche uniquement la sortie de la fenêtre lorsque l'exécutable se termine, et j'ai besoin de mettre à jour en temps réel ... ainsi que l'analyse la sortie

Mettez le nouveau code dans ... Le programme s'exécute, mais rien n'est porté sur l'écran, peut-être que je dois définir le processus pour écrire sur stdout? Il affichera chaque sortie lorsque le programme est annulé ou fini ... Toute la fonction agit de cette façon? Sûrement je fais quelque chose stupide ...

btw l'exécutable que j'appelle ne met pas en tampon la sortie ... quand appelé de la ligne de commande il sort comme le programme s'exécute ... Exécute tout sauf le bit SIGNAL fini. .

code:

monit::monit(QWidget *parent) : 
QDialog(parent), 
ui(new Ui::monit){ 

ui->setupUi(this); 


r = new QProcess(this); 

connect(r, SIGNAL(readyReadStandardError()), this, SLOT(updateError())); 
connect(r, SIGNAL(readyReadStandardOutput()), this, SLOT(updateText())); 
//connect(r, SIGNAL(started()), this, SLOT(updateExit())); 

} 

ProcChainMonitor::~ProcChainMonitor() 
{ 
    delete ui; 
} 

void ProcChainMonitor::on_buttonStart_clicked() 
{ 
    QString program = "prog"; 
    QStringList arguments; 
    arguments << "arg"; 

r->setWorkingDirectory("dir"); 
r->start(program, arguments); 
} 

void ProcChainMonitor::updateError() 
{ 

QByteArray data = r->readAllStandardError(); 
ui->textEdit->append(data); 

if (r->exitStatus()!= NULL){ 
    ui->textEdit->append("Exited"); 
    ui->textEdit->append(QString::number(r->exitCode())); 
} 
} 

void ProcChainMonitor::updateText() 

{ 

QByteArray data = r->readAll(); 
ui->textEdit->append(data); 

if (r->exitStatus()!= NULL){ 
    ui->textEdit->append("Exited"); 
    ui->textEdit->append(QString::number(r->exitCode())); 
} 

} 
+0

Ai-je besoin d'exécuter un travail d'arrière-plan? – JohnStudio

+0

Vous n'obtiendrez pas votre ui mis à jour tant que vous n'êtes pas en boucle. Essayez de vous connecter au signal readyRead et de lire la sortie dans l'emplacement –

Répondre

0

Regardez https://stackoverflow.com/questions/1000674/turn-off-buffering-in-pipe qui supprimera la mise en mémoire tampon et vous amener à recueillir des idées presque immédiatement (YMMV, je ne l'ai pas testé)

+0

Ou, si vous pouvez recompiler le processus enfant, ajoutez la commande setlinebuf (stdout); en haut de la classe main() du processus fils, pour indiquer au processus fils de ne mettre en tampon qu'une seule ligne à la fois. –

+0

Va utiliser les fonctions QProgress de Qt ... Mais merci! – JohnStudio

+0

FWIW, j'utilise QProcess dans mon code, mais je trouve toujours que l'appel de setlinebuf (stdout) dans le processus fils est bénéfique. (Sinon vous ne voyez pas toujours la sortie tout de suite dans le processus parent) –

Questions connexes