IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Multithreading Discussion :

Transmission de variables [QThread]


Sujet :

Multithreading

  1. #1
    Candidat au Club
    Homme Profil pro
    Alternance
    Inscrit en
    Janvier 2013
    Messages
    4
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    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 : 3
    Points
    3
    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 : Sélectionner tout - Visualiser dans une fenêtre à part
    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 : Sélectionner tout - Visualiser dans une fenêtre à part
    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 : Sélectionner tout - Visualiser dans une fenêtre à part
    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 : Sélectionner tout - Visualiser dans une fenêtre à part
    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 : Sélectionner tout - Visualiser dans une fenêtre à part
    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
    Ingénieur développement logiciels
    Inscrit en
    Mai 2008
    Messages
    26 858
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

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

    Informations forums :
    Inscription : Mai 2008
    Messages : 26 858
    Points : 218 575
    Points
    218 575
    Billets dans le blog
    120
    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

    Ma page sur DVP
    Mon Portfolio

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

  3. #3
    Candidat au Club
    Homme Profil pro
    Alternance
    Inscrit en
    Janvier 2013
    Messages
    4
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    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 : 3
    Points
    3
    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 : Sélectionner tout - Visualiser dans une fenêtre à part
    connect(this, SIGNAL(rep(unsigned char, int)), MainWindow, SLOT(rep_rec(unsigned char, int)));
    J'ai l'erreur suivante:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    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
    Candidat au Club
    Homme Profil pro
    Alternance
    Inscrit en
    Janvier 2013
    Messages
    4
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    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 : 3
    Points
    3
    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 : Sélectionner tout - Visualiser dans une fenêtre à part
    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 : Sélectionner tout - Visualiser dans une fenêtre à part
    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 : Sélectionner tout - Visualiser dans une fenêtre à part
    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 : Sélectionner tout - Visualiser dans une fenêtre à part
    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 : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    unsigned char tab[35];
    ......
    emit rep(tab, nboctet);
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    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
    Candidat au Club
    Homme Profil pro
    Alternance
    Inscrit en
    Janvier 2013
    Messages
    4
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    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 : 3
    Points
    3
    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
    Ingénieur développement logiciels
    Inscrit en
    Mai 2008
    Messages
    26 858
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

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

    Informations forums :
    Inscription : Mai 2008
    Messages : 26 858
    Points : 218 575
    Points
    218 575
    Billets dans le blog
    120
    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

    Ma page sur DVP
    Mon Portfolio

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

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

Discussions similaires

  1. probleme transmission de variable toute bete
    Par mereyj dans le forum Général JavaScript
    Réponses: 5
    Dernier message: 13/03/2006, 20h18
  2. [Sécurité] PHP 5 transmission de variables
    Par messier79 dans le forum Langage
    Réponses: 18
    Dernier message: 09/01/2006, 14h05
  3. Transmission de variable avec GET et header
    Par spirou dans le forum Langage
    Réponses: 10
    Dernier message: 03/01/2006, 19h04
  4. [FLASH MX] Transmission de variables entre 2 swf
    Par totoche dans le forum Flash
    Réponses: 3
    Dernier message: 12/10/2005, 15h54
  5. transmission de variables
    Par nicerico dans le forum ASP
    Réponses: 14
    Dernier message: 16/08/2004, 16h20

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo