Utiliser fopen avec un QTextEdit
Bonjour,
Je debute en Qt et C++.
J'utilise fopen pour recuperer la sortie d'une commande donnee et l'afficher au fur-et-a-mesure dans un QTextEdit.
Mes commandes ont le format suivant: commande [options] [fichiers]
Voici mon probleme: par exemple quand j'execute la chaine "commande -version", tout se passe bien, mais quand j'execute "commande -help", soudainement la sortie ne s'affiche plus dans mon QTextEdit mais dans le terminal (il s'agit ici de la meme commande que le premier exemple). Et il se produit la meme chose quand je lance la commande sans options mais seulement avec les fichiers attendus en parametres.
Toute aide est la bienvenue, alors n'hesitez pas !
Merci !!
utiliser un QProcess avec un QTextEdit
MERCI !!!!!!!
Je vais regarder la doc de cette classe.
Voici le resultat de mon travail:
Je rencontre des difficultes a utiliser un QProcess :aie:. D'abord je suis contraint de travailler en qt3 pour mon projet donc je vais expliquer pas a pas ma demarche pour que vous compreniez bien:D. Le principe est d'utiliser un QProcess pour recuperer la sortie d'une commande, afin de l'afficher dans un QTextEdit:
1_Je cree une fenetre principale de type QMainWindow dans laquelle j'insere comme widget principal un QTextEdit.
2_Je cree un QProcess dans le but d'executer la commande suivante: find /home/mch/grous -name *.cpp -print
3_ pour passer la chaine de caracteres a executer, qt3 et qt4 different:
* En qt4 la fonction start() est surchargee, de sorte que l'on peut soit lui donner un QString "programme" suivi d'un QStringList "arguments", soit lui donner une un unique QString regroupant les 2 informations ( programmes et arguments).
*En qt3, ces informations ne peuvent pas
etre passer en parametre de start(), il faut les specifier soit dans le constructeur (ce qui n'est pas possible en qt4), soit en appelant addArgument(QString), soit setArguments(QStringList) [ ces 2 methodes n'existent pas en qt4].
4_Je lis les donnes ecrites sur la sortie standart par le processus avec readStdout() qui renvoit un QByteArray (vide si aucune donnee ecrite) [l'equivalent qt4 serait readAll() ou read(qint64)]
5_j'appel la methode statique QString::fromLocal8Bit( char * ) avec mon QByteArray en parametre pour obtenir un QString Unicode.
6_j'insere ce QString dans mon textEdit.
Voici donc le code que j'ai d'abord essaye:
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35
|
#include <qapplication.h>
#include <qcstring.h> // pour utiliser QByteArray
#include <qprocess.h>
#include <qmainwindow.h>
#include <qtextedit.h>
int main( int argc, char ** argv ) {
QApplication app( argc, argv );
QMainWindow * fen = new QMainWindow;
fen -> setGeometry( 400, 400, 1000, 1000 );
app.setMainWidget( fen );
QTextEdit * textEdit = new QTextEdit( fen );
fen -> setCentralWidget( textEdit );
QProcess * process = new QProcess;
process -> addArgument( "find" );
process -> addArgument( "/home/mch/grous" );
process -> addArgument( "-name" );
process -> addArgument( "*.cpp" );
process -> addArgument( "-print" );
process -> start();
QByteArray data = process->readStdout();
QString str = QString::fromLocal8Bit( data );
textEdit -> append(str);
fen -> show();
return app.exec();
} |
Et la rien ne s'affiche dans mon QTextEdit !:calim2: J'ai donc voulu savoir ce que contenait le QString str: l'instruction
Code:
1 2
|
std::cout << "data\n" << str << std::endl; |
m'affiche dans le terminal "data" seulement ce qui suppose que str est vide. Pour le confirmer, j'ai ajoute l'instruction:
Code:
1 2
|
if( str.isNull() ) {std::cout << "str est nulle" << std::endl;} |
et la s'affiche le message "str est nulle". Je teste alors si le QByteArray data est vide:
Code:
1 2
|
if( data.isNull() ) {std::cout << "data est nulle" << std::endl;} |
et c'est le cas. Je remonte un cran au-dessus: la commande est-elle lancee ? J'ajoute donc juste apres la ligne process->start(); l'instruction:
Code:
1 2 3 4
|
int i = 0;
while ( process -> isRunning() ) { i++; }
std::cout << i << std::endl; |
(ps: isRunning() equivaut en Qt4 a tester si la valeur de retour de state() est QProcess::Running)
Et la i vaut 243343 donc le processus tourne bien !
Et de facon surprenante, en ajoutant cette boucle, j'obtiens l'affichage attendu dans mon QTextEdit ! Et de plus tous mes tests deviennent positives ( data non nul, str non nul ...). J'en deduit qu'il faut appeler isRunning() pour "debloquer la situation", je remplace donc ma boucle while par:
et ca ne marche plus meme si je l'appel plusieurs fois.
tout ce qui precede est aussi observe pour la commande ls -lh que j'ai teste.
Independamment de cela, j'ai une question de comprehension concernant la methode addArgument(QString): est-il possible d'ecrire :
Code:
1 2 3 4
|
QString s = find /home/mch/grous -name *.cpp -print;
process->addArgument(s);
process->start(); |
plutot que faire plusieurs addArguments(QString) ? En Qt4 c'est possible de le faire avec la methode start(QString,OpenMode) ou le QString inclut le nom du programme et ses arguments. Je pense que ce n'est pas possible ici car ca ne fonctionne pas, et de plus il existe une methode setArguments(QStringList) qui permet de specifier le nom du programme (premier element de la liste) et ses arguments ensuite. Confirmez le moi SVP.
PS: le phenomene decrit au-dessus est identique quand a la place de addArgument(QString), j'emploi setArgument(QStringList):
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35
|
#include <qapplication.h>
#include <qcstring.h> // pour utiliser QByteArray
#include <qprocess.h>
#include <qmainwindow.h>
#include <qtextedit.h>
#include <qstringlist.h>
int main( int argc, char ** argv ) {
QApplication app( argc, argv );
QMainWindow * fen = new QMainWindow;
fen -> setGeometry( 400, 400, 1000, 1000 );
app.setMainWidget( fen );
QTextEdit * textEdit = new QTextEdit( fen );
fen -> setCentralWidget( textEdit );
QProcess * process = new QProcess;
QStringList l;
l << "find" << "/home/mch/grous" << "-name" << "*.cpp" << "-print";
process -> setArguments(l);
process -> start();
process -> start();
QByteArray data = process->readStdout();
QString str = QString::fromLocal8Bit( data );
textEdit -> append(str);
fen -> show();
return app.exec();
} |
Conclusion: dans tous les cas la commande est lancee ( avec ou sans l'appel de isRunning() dans un while ), d'ailleurs j'ai aussi teste la commande "touch fichier" et le fichier est bien creer. Par contre, pour recuperer la sortie (quand elle existe, ce qui est pqs le cas pour "touch"), je dois faire suivre l'appel de start(); par while( process->isRunning() ); Pourquoi ?
Je pourrai vous donnez un autre exemple concernant la commande que je dois executer dans le cas de mon projet, mais je crois que vous en avez assez ?:oops: J'aimerai que vous m'aidiez a faire la "mise au point" !:cry:
Toutes les idees sont le bienvenue.
Merci beaucoup de votre aide !!!