Publicité
+ Répondre à la discussion
Affichage des résultats 1 à 6 sur 6
  1. #1
    Invité de passage
    Homme Profil pro Tony Lecointre
    Alternance
    Inscrit en
    janvier 2013
    Messages
    4
    Détails du profil
    Informations personnelles :
    Nom : Homme Tony Lecointre
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Alternance
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : janvier 2013
    Messages : 4
    Points : 1
    Points
    1

    Par défaut Transmission de variables

    Bonjour à tous,

    j'aimerai avoir un coup de main sur la fonctionnalité du thread sur QT. En effet, je suis sur un programme permettant de recevoir des données depuis un port série. J'ai besoin d'exécuter une tache en parallèle, et j'ai donc décidé d'utiliser le Thread.

    Mon problème est que dans ce Thread, j'ai besoins d'une variable qui est utilisé dans mon MainWindow (Variable de type HANDLE qui me permet de me connecter au port série), et je n'arrive pas à la récupérer..

    Voici les parties du code qui seront utiles pour résoudre mon problème:

    threadevent.h:
    Code :
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    #ifndef THREADEVENT_H
    #define THREADEVENT_H
    #include <QThread>
    #include "mainwindow.h"
     
    class ThreadEvent : public QThread
     {
         Q_OBJECT
     
     public:
         void run();
     
    //signals:
       // void arg(HANDLE hSerial); //Ceci est ce que j'avais trouvé sur internet                        //mais je n'ai pas réussi à l'utiliser
     };
     
    #endif // THREADEVENT_H;

    threadevent.cpp:
    Code :
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    #include "threadevent.h"
    #include "mainwindow.h"
     
    void ThreadEvent::run()
     {
        DWORD dwBytesRead;
        unsigned char *szBuff;
        printf("je rentre dans le thread");
        while (1)
        {
            if(ReadFile(hSerial, szBuff, 1, &dwBytesRead, NULL))
            {
                printf(" buffer de reception %ld bytes: \n\n %s\n\n\n", dwBytesRead, szBuff);
            }
        }
     }
    mainwindow.h:
    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
    class MainWindow : public QMainWindow
    {
        Q_OBJECT
     
     
    public:
        ....
        unsigned char *szBuff;
        DWORD dwBytesRead;
        HANDLE hSerial;
        ....
     
     
    //signals:
        //void arg_thread(HANDLE hSerial); //Ceci est ce que j'avais trouvé sur internet mais je n'ai pas réussi à l'utiliser
     
    private:
        Ui::MainWindow* ui;
     
    public slots:
        .....
     
    private slots:
     
    .....
     
    };
     
    #endif // MAINWINDOW_H

    mainwindow.cpp:
    Code :
    1
    2
    3
    4
    5
    6
    7
    MainWindow::MainWindow(QWidget *parent) :
        QMainWindow(parent),
        ui(new Ui::MainWindow)
    {
        ui->setupUi(this);
        .... // Je suppose qu'ici il y aura le traitement du signal a envoyer..
    }
    et enfin main.cpp:
    Code :
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    #include <QtGui/QApplication>
    #include "mainwindow.h"
    #include "threadevent.h"
     
    void interrupt(HANDLE hSerial, unsigned char *szBuff, DWORD dwBytesRead);
     
    int main(int argc, char *argv[])
    {
        QApplication a(argc, argv);
        MainWindow w;
        w.show();
     
        ThreadEvent thread;
        thread.start();
     
        return a.exec();
    }
    Voila, mon problème vient donc de la fonction ReadFile dans mon run(), que je ne peux pas utiliser puisque le hSerial n'est pas reconnu et donc il ne sait pas sur quel port lire.. (Je ne peux d'ailleurs pas compiler le projet à ce moment puisque la variable hSerial de run() n'éxiste pas !).

    Sinon, l'appel au Thread fonctionne correctement lorsque je remplace le contenu par un simple printf afin de vérifier si le fonctionnement est correcte..

    Je fais donc appelle à vous, car cela est très important et j'ai grandement besoins de votre aide !

    Bien cordialement, Tony.

  2. #2
    Responsable 2D/3D/Jeux

    Avatar de LittleWhite
    Homme Profil pro Alexandre Laurent
    Ingénieur développement logiciels
    Inscrit en
    mai 2008
    Messages
    16 161
    Détails du profil
    Informations personnelles :
    Nom : Homme Alexandre Laurent
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : mai 2008
    Messages : 16 161
    Points : 76 204
    Points
    76 204

    Par défaut

    Bonjour,

    Dans ce cas, une solution (peut être pas la meilleure) sera de passer un pointeur (ou une référence) de votre MainWindow au constructeur de ThreadEvent afin que cette variable soit mémorisé (copiée) dans la classe (dans une variable de la classe).
    De plus, je vous conseillerai de faire plus attention à la visibilité de vos variables, en effet, je vois des variables membres de MainWindow déclarée publique alors que ce cas arrive rarement en C++. Je vous conseillerai de lire ou revoir un cours sur la conception objet. Souvent, ces variables sont privées et si vraiment il est nécessaire d'y avoir un accès, on ajoute un accesseur (un getter).
    Vous souhaitez participer à la rubrique 2D / 3D / Jeux ? Contactez-moi
    La rubrique a aussi un blog !

    Ma page sur DVP
    Mon Portfolio

    Qui connaît l'erreur, connaît la solution.

  3. #3
    Invité de passage
    Homme Profil pro Tony Lecointre
    Alternance
    Inscrit en
    janvier 2013
    Messages
    4
    Détails du profil
    Informations personnelles :
    Nom : Homme Tony Lecointre
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Alternance
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : janvier 2013
    Messages : 4
    Points : 1
    Points
    1

    Par défaut

    Bonjour,

    tout d'abord merci de m'avoir apporté une réponse. En fouillant un peu dans différents sujet j'ai réussi à adapter le code pour que cela fonctionne. Je n'avais pas vraiment bien assimilé la fonction connect et son fonctionnement.

    Seulement, j'ai un autre problème. Une fois que les variables que je désirai envoyer dans le thread sont fonctionnel, mon code fonctionne et le thread tourne bien. Maintenant, j'aimerai renvoyer ce que le thread m'a calculé dans le MainWindows.

    J'ai utilisé le même protocole, c'est à dire création d'un SLOT dans le MainWindow et d'un SIGNAL dans le thread, puis j'ai utilisé la fonction connect. Mais le probleme est que dans la fonction connect, il semblerai que le "MainWindow" ne soit pas accepté.

    Voici comment je l'ai écrit dans la fonction run() du thread.cpp
    Code :
    connect(this, SIGNAL(rep(unsigned char, int)), MainWindow, SLOT(rep_rec(unsigned char, int)));
    J'ai l'erreur suivante:
    Code :
    expected primary-expression before ',' token
    J'avais la même chose lorsque je voulais envoyer du MainWindow vers le thread, mais cela venait du thread que j'avais mal déclaré ( je n'avais pas utilisé le thread = new MonThread(); etc...)

    Merci à toi si tu repasses par la !

    Cordialement, Tony.

    PS: Pour les variables, je les ai donc passé en privé. Je ne vois pas la différence, mais je pense que cela ne peut être que mieux !

  4. #4
    Invité de passage
    Homme Profil pro Tony Lecointre
    Alternance
    Inscrit en
    janvier 2013
    Messages
    4
    Détails du profil
    Informations personnelles :
    Nom : Homme Tony Lecointre
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Alternance
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : janvier 2013
    Messages : 4
    Points : 1
    Points
    1

    Par défaut

    Désolé du double post, mais c'est pas clair sinon..

    Donc, j'ai réussi à résoudre mon problème, et voici ce que donne mon code:

    mainwindow.h
    Code :
    1
    2
    3
    4
    signals:
        void arg_thread(HANDLE hSerial, DWORD dwBytesRead, unsigned char *szBuff);
    private slots:
        void rep_rec(unsigned char* tab, int nboctet);
    mainwindow.cpp
    Code :
    1
    2
    3
    4
    5
    ThreadEvent *thread = new ThreadEvent();
        connect(this, SIGNAL(arg_thread(HANDLE, DWORD , unsigned char*)), thread, SLOT(arg(HANDLE, DWORD , unsigned char*)));
        connect(thread, SIGNAL(rep(unsigned char*, int)), this, SLOT(rep_rec(unsigned char*, int)));
        emit arg_thread(hSerial, dwBytesRead, szBuff);
        thread -> start();
    ainsi que la fonction de réception:
    Code :
    1
    2
    3
    4
    5
    void MainWindow::rep_rec(unsigned char* tab, int nboctet)
    {
        printf(" je rentre dans le rep_rec");
        affiche_trame_R(tab, nboctet);
    }
    Maintenant, le thread.h:
    Code :
    1
    2
    3
    4
    5
    private slots:
        void arg(HANDLE hSerial, DWORD dwBytesRead, unsigned char *szBuff);
     
    signals:
        void rep(unsigned char* tab, int nboctet);
    et le thread.cpp ainsi que la fonction de réception:

    Code :
    1
    2
    3
    unsigned char tab[35];
    ......
    emit rep(tab, nboctet);
    Code :
    1
    2
    3
    4
    5
    6
    void ThreadEvent::arg(HANDLE hSerial, DWORD dwBytesRead, unsigned char *szBuff)
    {
        printf("je rentre dans la fonction arg");
        m_hSerial = hSerial;
        m_szBuff = szBuff;
        m_dwBytesRead = dwBytesRead;
    Voila, et ça, ça fonctionne !!!! Mais, le problème vient du fait que le tableau "tab" ne se transfert pas du thread vers le MainWindow. Pourquoi ? Je ne sais pas.. Parce que le "nboctet" qui est un int passe normalement..

    Je précise que nboctet et tab ont bien une valeur dans le thread, c'est à dire que mon threal calcul ces valeurs, puis je les transmet au MainWindow. nboctet passe, tab passe pas.

    Donc mon problème est la, si vous aviez une solution..

  5. #5
    Invité de passage
    Homme Profil pro Tony Lecointre
    Alternance
    Inscrit en
    janvier 2013
    Messages
    4
    Détails du profil
    Informations personnelles :
    Nom : Homme Tony Lecointre
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Alternance
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : janvier 2013
    Messages : 4
    Points : 1
    Points
    1

    Par défaut

    Problème résolue, je suis finalement passer par des variables intermédiaire à la place d'envoyer le tableau directement (Utilisation d'une boucle for pour faire plusieurs emit() ).

    Merci en tout cas ! RESOLUE !

  6. #6
    Responsable 2D/3D/Jeux

    Avatar de LittleWhite
    Homme Profil pro Alexandre Laurent
    Ingénieur développement logiciels
    Inscrit en
    mai 2008
    Messages
    16 161
    Détails du profil
    Informations personnelles :
    Nom : Homme Alexandre Laurent
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : mai 2008
    Messages : 16 161
    Points : 76 204
    Points
    76 204

    Par défaut

    En place de vos printf() de debogage, je vous conseille d'utiliser qDebug() (notamment si vous êtes dans du code utilisant Qt).

    Transférer de lourds éléments par le système de signal/slot de Qt me parait toujours dangereux (en terme de performance). Mais, si je me rappelle ce que j'ai entendu aux Qt DevDays, cela n'est lourd que si on transfert les éléments un par un, car le reste n'est qu'un jeu de pointeur.
    Vous souhaitez participer à la rubrique 2D / 3D / Jeux ? Contactez-moi
    La rubrique a aussi un blog !

    Ma page sur DVP
    Mon Portfolio

    Qui connaît l'erreur, connaît la solution.

+ Répondre à la discussion
Cette discussion est résolue.

Liens sociaux

Règles de messages

  • Vous ne pouvez pas créer de nouvelles discussions
  • Vous ne pouvez pas envoyer des réponses
  • Vous ne pouvez pas envoyer des pièces jointes
  • Vous ne pouvez pas modifier vos messages
  •