[QT] inclure programme dans GUI

Résolu/Fermé
lmb - 8 avril 2008 à 00:49
Char Snipeur Messages postés 9813 Date d'inscription vendredi 23 avril 2004 Statut Contributeur Dernière intervention 3 octobre 2023 - 18 avril 2008 à 08:32
Bonjour,

J'ai un programme X composé de 3 fichiers .h et 3 fichiers .cpp (dont le main) qui me fait une opération d'extraction de fichier texte.

J'ai crée une interface QT me permettant de lancer l'exécutable de ce programme X via le code ci-dessous contenu dans un slot.

QProcess::startDetached (chemin d accès du .exe);

Tout marche bien.

Maintenant je souhaite intégrer ce code du programme X dans le code de mon interface (pour par exemple passer des parametres ..etc). J'ai donc remplacé le code du slot (depuis lequel je lançais mon Qprocess) par le code du main du programme X ,et j'ai ajouté les includes de mes fichiers .h.

Le résultat est que ça plante. Je ne parviens pas a comprendre ce qui se passe
Je compile ac la console QT command prompt.
L'erreur est :
g++: object_script.Code : No such file or directory
mingw32-make[1]:***["release\code] Error 1
mingw32-make : ***[release] Error 2


Merci pour votre aide !

lmb

21 réponses

mamiemando Messages postés 33387 Date d'inscription jeudi 12 mai 2005 Statut Modérateur Dernière intervention 27 novembre 2024 7 803
8 avril 2008 à 10:19
En fait je pense que QT permet d'appeler directement ton programme en lui passant des paramètres. Sinon tu peux par exemple utiliser la fonction du langage C : execvp.

Bonne chance
0
Il permet seulement de lancer un .exe en lui passant des parametres ?

Moi je voudrais que ce programme soit dans le slot ... le prog principal de ce programme X est tout petit et fait appel à des fontions d'autres fichiers inclus dans le projet. C'est pas possible ça ac QT?
0
Char Snipeur Messages postés 9813 Date d'inscription vendredi 23 avril 2004 Statut Contributeur Dernière intervention 3 octobre 2023 1 298
9 avril 2008 à 08:31
Salut, si c'est possible.
Il faut que tu renomme ton main de ton programme principal. Par exemple mainprog. puis dans le .cpp où tu as ton QProcess, tu met au tout début une ligne :
int mainprog(int ,char**);
et ensuite, tu fait un connecte de slot SLOT(mainprog);
Mais attention, avec QT il est possible qu'il faille déclarer préalablement les fonctions que l'on veux utiliser en slot comme tel.
0
Ah merci ça m'intéresse ... tu peux pousser un peu plus stp ...

Mon slot mainprog, je l'implante dans une classe 'MyProgs'.

Je le met où le int mainprog(int ,char**); ?
au début de l'implémentation du slot ? et la fin faut faire un return alor ?

Et le QProcess je vois pas où il intervient ? y'en a plus besoin si je met le code de mon main du prog X dans le slot mainprog ... non ?

Et ta dernière phrase ... tu penses qu'il faut déclarer les fonctions que j'utilise dans mon slot en tant que slot aussi ?... hum hum ... je vois pas du tout, ça a du sens ?

je suis désolé de te reprendre sur chacune de tes phrases,mais merci bcp pour ton aide, j'aimerai tellement trouver une solution.

J'y pense ... dans un forum on m'a parlé de thread ... t'en pense quoi ? j'y connais rien par contre là dedans.

Merci beaucoup

lmb
0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
Char Snipeur Messages postés 9813 Date d'inscription vendredi 23 avril 2004 Statut Contributeur Dernière intervention 3 octobre 2023 1 298
10 avril 2008 à 08:33
je pense que tu n'as pas compris ce que je te suggérait.
Déjà, je pense en effet qu'il faut passer par un thread, sinon, tu va bloquer ta fenètre durant l'appel à mainprog, mais cela tu pourra t'en occuper par la suite.
Je recommence : ton programme X (comme tu l'appel) tu n'y touche pas, tu renomme juste le main en mainprog.
Erreur plus grave, si tu mets mainprog comme fonction membre d'une class, la fonction n'aura rien à voir avec ton programme X, ce sera MyProgs::mainprog() et pas ::mainprog(), nuance de taille.
ce que je te conseil de tester en premier lieu, c'est juste dans ton main.cpp de QT de rajouter la déclaration de mainprog au début, puis de faire juste un "connect" avec le signal que tu veux.
Le but est d'utiliser mainprog du programme X comme une fonction, genre "sinus" si tu voi ce que je veux dire.
0
Char Snipeur Messages postés 9813 Date d'inscription vendredi 23 avril 2004 Statut Contributeur Dernière intervention 3 octobre 2023 1 298
10 avril 2008 à 08:42
J'ai retrouvé mon exemple de thread. Pour l'adapter à ton problème, en gros ça serait;
class MainProg : public QThread
{
      (int) *(void) Prg;
      public :
      MainProg():Prg(mainprog){};
      virtual void run();
}
void MainProg::run()
{
    *Prg();// poionteur de fonction vers mainprog, donc devant lancer mainprog
}

après, il y a peut être plus simple.
0
Merci pour ton aide !

Il paraît que les threads c'est assez dur ... mais bon, vu que tu me donnes le code, je veux bien essayer :)
J'ai pas pu encore testé mais j'ai qqs petites questions ...

Je renomme le main de X en mainprog ... mais "main" c'est pas un mot obligatoire ?
Du coup, je dois joindre le fichier main.cpp de X au projet ? je le renomme pour l'occasion main_prog.cpp alors ?
Et dans ton code... "mainprog" il est pas connu si ? il se déclare comment ? faut faire un include "main_prog" ici ?

Je comprends très bien l'idée mais dans la réalisation c'est plus flou ... comme tu peux le voir, lol

Merci bcp.
Si ça marche comme tu dis, j'en serai ravi parce que personne a su me dire une solution claire à ce problème.

ps : y'a pas un petit "void" devant MainProg() dans ton code??
0
Char Snipeur Messages postés 9813 Date d'inscription vendredi 23 avril 2004 Statut Contributeur Dernière intervention 3 octobre 2023 1 298
11 avril 2008 à 08:38
Ce qui est bien en C, c'est que le nom du fichier on s'en tape, alors ton main.cpp du prog X, t'en fait ce que tu veux.
Justement, si je te fait renommer main() de X en mainprog(), c'est parce que justement c'est un mot obligatoire, et qu'il existe déjà dans ton interface graphique.

Et dans ton code... "mainprog" il est pas connu si ? il se déclare comment ? faut faire un include "main_prog" ici ?
Pour la troisième fois, tu le déclare là où tu l'utilise. Passe par un include ou non, comme tu veux.

-Pour ton P.S. si tu parle de la ligne
     MainProg():Prg(mainprog){};
absolument pas, c'est un constructeur ! donc pas de void.
0
:( j'arrive pas a y faire fonctionner. T'es sur de "(int) *(void) Prg;"

Peut être je fais mal ... je te montre le code :


/*****************************************************************************
* MainProg.h
*****************************************************************************/
// class pour lancer programme extraction, fait appelle au main de ce programme

#ifndef DEF_MAINPROG
#define DEF_MAINPROG

#include <QThread>
/*****************************************************************************
* Include for Extract_txt Mems Post-Processing
*****************************************************************************/
#include <fstream> // file output
#include <iostream> // file output
#include <string> // argument handling
#include <sstream> // convert type
#include "ext_Extract_txt.h"
#include "ext_Variables_Globales.h"
/******************************************************************************/

class MainProg : public QThread
{
public:
(int) *(void) Prg;
public :
MainProg():Prg(mainprog){};
virtual void run();
int mainprog();
}
#endif


/*****************************************************************************
* MainProg.cpp
*****************************************************************************/

#include "MainProg.h"

void MainProg::run()
{
*Prg();// pointeur de fonction vers mainprog, donc devant lancer mainprog
}

int MainProg::mainprog()
{
while ( !(end_file) )
{
ExtractRawDataLine();
DisplayLine();
}
return EXIT_SUCCESS;
}


le mainprog c'est mon main de X que j'ai collé ici.

et enfin le code ou je suis censé l'utiliser ...


// class MyProgs, contenant les slots reliés au bouton de ma GUI
void MyProgs::LaunchProcess_Extract()
{
MainProg Programme_Extraction;
Programme_Extraction.run();

}


Est-ce comme ca que tu le voyais ?
J'ai pas mal d'erreurs, genre il aime le "int" de "(int) *(void) Prg;"
et d'autres que je ne comprends pas trop...

Merci !!!
0
Char Snipeur Messages postés 9813 Date d'inscription vendredi 23 avril 2004 Statut Contributeur Dernière intervention 3 octobre 2023 1 298
11 avril 2008 à 17:35
Arg, tu n'as rien compris, ou rien lu de ce que j'ai écris ?
bon, pour le (int) *(void)Prg je ne suis pas sur du tout. C'est êux être int*Prg(void); cherche dans pointeur de fonction.
Qu'est-ce que tu ne comprends pas quand je te dit que le main de ton programme principale tu le renomme juste mainprog() ????? Pourquoi me colle tu un MainProg:: juste avant ?
remarque, ce que tu as écris est peut être plus intelligent que ce que je te proposait de faire :
/*****************************************************************************
* MainProg.h
*****************************************************************************/
// class pour lancer programme extraction, fait appelle au main de ce programme

#ifndef DEF_MAINPROG
#define DEF_MAINPROG

#include <QThread>
/*****************************************************************************
* Include for Extract_txt Mems Post-Processing
*****************************************************************************/
#include <fstream> // file output
#include <iostream> // file output
#include <string> // argument handling
#include <sstream> // convert type
#include "ext_Extract_txt.h"
#include "ext_Variables_Globales.h"
/******************************************************************************/

class MainProg : public QThread
{
public:
(int) *Prg(void) ;
public :
MainProg():Prg(mainprog){};
virtual void run();
}
#endif


/*****************************************************************************
* MainProg.cpp
*****************************************************************************/

int mainprog()
{
while ( !(end_file) )
{
ExtractRawDataLine();
DisplayLine();
}
return EXIT_SUCCESS;
} 
/*****************************************************************************
* MainProg.cpp
*****************************************************************************/
 // class MyProgs, contenant les slots reliés au bouton de ma GUI
#include "mainprog.h"
int mainprog(); // declaration de la fonction principale du programme X

void MyProgs::LaunchProcess_Extract()
{
MainProg Programme_Extraction(mainprog);
Programme_Extraction.run();

}
Avec ta solution de faire de mainprog une fonction membre d'une classe, tu peux te passer de Prg, dans MainProg::run il suffit alors d'appeler mainprog() à la place de mon *Prg.
Par contre, je te conseil de mettre à ce moment là le mainprog en private.
Note d'ailleur que comme tu fait, il est possible de garder la dénomination de main !
Très bonne solution que tu propose là après reflexion, juste quelques détails à régler.
0
Ah lala je suis désolé mais c'est pas clair.
Dans MainProg.cpp, il doit avoir l'impléemtantation de la classe MainProg déclarée ds le.h ... or la, tu m'y colles mon main du programme X. par exemple, MainProg::run() doit etre impléenteé ds ce fichier logiquement. là, il est nulle part.

Si je poursuis sur ma façon de faire,
le (int) *Prg(void) ; n'est toujours pas accepté.

Je vais approfondir mais si tu peux me donner un code plus clair, je serai trés heureux.

Je te soule un peu, mais je te remercie vivement de ton aide ;)
0
Char Snipeur Messages postés 9813 Date d'inscription vendredi 23 avril 2004 Statut Contributeur Dernière intervention 3 octobre 2023 1 298
12 avril 2008 à 16:27
en fait, c'est vrai que tu peux tout simplement inclure la fonction main de X comme fonction membre de ta class MainProg, donc tu vire Prg qui ne sert en fait à rien !
Ensuite, j'ai l'impression que ce qui te manque, c'est des notions de C. Chaque fonction doit être déclaré dans les fichiers où elle est utilisée. Mais chaque fonction ne doit être définie (ou implémenté) qu'une seule fois pour l'ensemble du programme.
Aprsè, tu arranges tout ça dans le sens que tu veux, tu défini les fonctions dans les fichiers que tu veux.
Ensuite, c'est plus une question de lisibilité pour s'y retrouver.
0
Char Snipeur Messages postés 9813 Date d'inscription vendredi 23 avril 2004 Statut Contributeur Dernière intervention 3 octobre 2023 1 298
14 avril 2008 à 08:43
/*****************************************************************************
* MainProg.h
*****************************************************************************/
// class pour lancer programme extraction, fait appelle au main de ce programme

#ifndef DEF_MAINPROG
#define DEF_MAINPROG

#include <QThread>
/*****************************************************************************
* Include for Extract_txt Mems Post-Processing
*****************************************************************************/
/******************************************************************************/

class MainProg : public QThread
{
public :
MainProg():{};
virtual void run();
private:
int mainprog();
}
#endif


/*****************************************************************************
* MainProg.cpp
*****************************************************************************/

#include <fstream> // file output
#include <iostream> // file output
#include <string> // argument handling
#include <sstream> // convert type
#include "ext_Extract_txt.h"
#include "ext_Variables_Globales.h"
#include "MainProg.h"

void MainProg::run()
{
mainprog();// pointeur de fonction vers mainprog, donc devant lancer mainprog
}

int MainProg::mainprog()
{
while ( !(end_file) )
{
ExtractRawDataLine();
DisplayLine();
}
return EXIT_SUCCESS;
}


// class MyProgs, contenant les slots reliés au bouton de ma GUI
void MyProgs::LaunchProcess_Extract()
{
MainProg Programme_Extraction;
Programme_Extraction.start();

} 
Voilà ce que je te propose. après, il est même peut être possible de se passer de LaunchProcess_Extract et de lancer directement Programme_Extraction.start().
0
ok merci, ça compile ... mon programme est censé ouvrir la console , jai donc ajouté "CONFIG += CONSOLE" au .PRO
le programme tourne mais pas correctement. Celui-ci utilise des variables globlales que viennent modifier mes fonctions du mainprog, mais la elles ne se modifient plus, elles restent a leur valeur initiales ... je vois pas trop pourquoi ?
0
Char Snipeur Messages postés 9813 Date d'inscription vendredi 23 avril 2004 Statut Contributeur Dernière intervention 3 octobre 2023 1 298
15 avril 2008 à 08:25
1. est tu sur que le mainprog est bien lancé et s'exécute correctement ?
2. met des printf pour vérifier que mainprog se déroule correctement (qu'il modifie bien tes variable globale au moins dans son espace.
Si le problème persiste, ouvre un nouveau message.
0
J'ai trouvé mieux ! utiliser
QProcess.start(chemin d'accès du .exe de X , liste des arguments a passer au .exe de X)


ça me permet de pas inclure mon code dans le projet où j'ai mon code GUI, et je peux quand même envoyer les paramètres au programme X. Je ne savais pas comment utiliser cet objet mais là maintenant j'ai compris !

Merci pour ton aide !
0
Char Snipeur Messages postés 9813 Date d'inscription vendredi 23 avril 2004 Statut Contributeur Dernière intervention 3 octobre 2023 1 298
17 avril 2008 à 08:44
à mon avis, c'est moins bien !
QProcess lance le programme de manière séparé. Les principales conséquences sont :
- pas de mémoire partagé, l'exe ne modifiera en rien le programme en cour;
- tu peux passer des paramètres en lecture, mais pas en écriture, ça ne t'apporte rien par rapport au thread;
- Tu as moins d'interaction avec ton programme X.
Il est étonnant que QThread ne permette pas de passer des raguments, mais tu peux rusé en mettant des variable supplémentaires dans ta classe hérité, arguments que tu utilisera alors dans mainprog.
class MainProg : public QThread
{
   double& param2;
   int& param1;
  public :
    MainProg(int& a,double& b):param1(a),param2(b){};
    virtual void run();
  private:
    int mainprog();
}
0
Oui je vois ce que tu veux dire quand tu dis qu'on perd en interaction.

Par contre je suis pas d'accord, on peut aussi bien passer des paramètres au prog X par qprocess.write (recupéré dans X par un stdin , qu'en recevoir du prog X par qprocess.read (envoyé par X par stdout).

Je pense que dans un premier temps je vais essayer de fonctionner comme ceci.
Juste une chose que je doute, si je procéde par QProcess.start("chemin d'acces du .exe de X", arguments pr X), est-ce que la console va bien s'ouvrir pour afficher les résultats de X ( X est un programme console).

Mercii
0
Char Snipeur Messages postés 9813 Date d'inscription vendredi 23 avril 2004 Statut Contributeur Dernière intervention 3 octobre 2023 1 298
17 avril 2008 à 16:57
bien entendu, tu peux lire et ecrire sur les entrés sorties standard, MAIS tu ne peux pas modifier les arguments que tu passe.
Ensuite, récupérer la sortie standard, qui suppose une synchronisation du flux, puis un traitement des données lu : ça fait du travail supplémentaire pas forcement évident à réaliser.

Je trouve ça vraiment dommage que tu laisse tomber le QThread qui était presque fini pour t'orienter vers un truc aussi bateau et peux élégant que le QProcess...

Au sujet du thread et des variables globales non modifié. As tu vérifier que ton thread était bien terminé avant de lire tes variables globales ? il faut un certain temps pour lancer et exécuter un thread, donc si tu fait :
QThread a();
...
a.start();
//lecture des variables globales
C'est presque certain qu'elles ne seront pas modifié, il faut faire un a.wait() avant de lire ces variables, pour être sur.
0
Ouais mais je n'ai pas a communiqué tant que ça avec mon programme, envoyer des arguments au début peut être suffissant.
Dans un premier temps, je vais essayer ac QProcess, après j'évoulerai vers QThread quand ça marchera bien. Merci de tes conseils en tout cas. Je prends bien tout en note.

Aurais-tu juste la réponse a ma question précédente sur l'ouverture de la console pour mon prog X ?
Je voudrais qu'elle se lance lors du process.start ... que le programme s'execute avec l'affichage prévue ds la console, puis qu'a la fin, elle se ferme , et que je revienne a ma fenetre.

Quand j'utiliserai Qthread je pourrai faire l'affichage ds une fenetre aussi alors, ca sera mieux, mais pour le mmt, si ca pouvait marcher avec la console, je serai trés heureux !

merciiii !
0