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

Threads & Processus C++ Discussion :

Utilisation de 'run' de QtConcurrent


Sujet :

Threads & Processus C++

Vue hybride

julieng31 Utilisation de 'run' de... 21/01/2016, 14h56
yan Salut. Dans ton cas, comme... 25/01/2016, 19h46
julieng31 Merci Yan, ça doit en effet... 27/01/2016, 17h11
julieng31 Bonjour Yan, j'ai suivi... 05/02/2016, 10h20
julieng31 Juste une petite correction... 05/02/2016, 10h40
Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre confirmé
    Inscrit en
    Mars 2007
    Messages
    134
    Détails du profil
    Informations forums :
    Inscription : Mars 2007
    Messages : 134
    Par défaut Utilisation de 'run' de QtConcurrent
    Bonjour,

    je souhaiterais afficher sur une carte des points. Lorsque je clique sur un bouton, les coordonnées de ses points se mettent à jour, ils se déplacent donc sur la carte jusqu'à ce que je clique à nouveau sur le bouton. Pour cela, j'ai écris le code suivant :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    class tabVisu : public QWidget {
        Q_OBJECT
    ...
    private:
        bool loopRun;
    private slots:
        void playDisplay(const bool state);
    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
     
    tabVisu::tabVisu(QWidget *parent) : QWidget(parent) {
        loopRun= false;
        QPushButton * playBt = new QPushButton(tr("Jouer"));
        playBt->setCheckable(true);
        connect(playBt, SIGNAL(clicked(bool)), this, SLOT(playDisplay(bool)));
    }
     
    void tabVisu::playDisplay(const bool state) {
        loopRun = state;
        QtConcurrent::run(this, &tabVisu::infiniteLoopDisplay);
    }
     
    void tabVisu::infiniteLoopDisplay() const {
        while(loopRun) {
            // calcul des nouvelles positions et modification de l'affichage sur la carte
        }
    }
    Ca compile mais lorsque j'appuie sur le bouton, j'obtiens le message d'erreur : "ASSERT failure in QCoreApplication::sendEvent: "Cannot send events to objects owned by a different thread. Current thread 24769638. Receiver '' (of type 'MainWindow') was created in thread 19729290"

    J'essaye de comprendre ce qui ne fonctionne pas mais découvrant QtConcurrent, je n'arrive pas m'en sortir. Pourriez-vous m'aider ? Merci !

  2. #2
    yan
    yan est déconnecté
    Rédacteur
    Avatar de yan
    Homme Profil pro
    Ingénieur expert
    Inscrit en
    Mars 2004
    Messages
    10 035
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : Ingénieur expert
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Mars 2004
    Messages : 10 035
    Par défaut
    Salut.
    Dans ton cas, comme tu veux une boucle dans un thread, il faut mieux que tu créé un QThread.

    Pour l'erreur, il faudrait voir ce que tu fait dans infiniteLoopDisplay. Mais en gros, tu appel dans infiniteLoopDisplay des fonctions IHM de widget. Ce qui n'est pas possible en Qt. Une manière de contourner le problème est d'utiliser des signal/slot et d’émettre les signaux dans ta fonction. Tu trouva des infos dans la FAQ.

    Yan

  3. #3
    Membre confirmé
    Inscrit en
    Mars 2007
    Messages
    134
    Détails du profil
    Informations forums :
    Inscription : Mars 2007
    Messages : 134
    Par défaut
    Merci Yan, ça doit en effet venir du fait que je modifie bien des widgets (qcustomplot) dans la fonction infiniteLoopDisplay. Je vais lire la FAQ et je poste mon code une fois que j'ai avancé.

    Merci !

  4. #4
    Membre confirmé
    Inscrit en
    Mars 2007
    Messages
    134
    Détails du profil
    Informations forums :
    Inscription : Mars 2007
    Messages : 134
    Par défaut
    Bonjour Yan,

    j'ai suivi tes conseils et une bonne partie commence à marcher. Quand je lance le thread, les signaux sont envoyés et reçus et la carte évolue bien. Par contre, quand je veux stopper l'animation, tout se fige... Il y a quelque chose que je ne fais pas bien ? Merci d'avance !

    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
     
    class tabVisu : public QWidget {
    private:
        QPushButton * playBt = nullptr;
    private slots:
        void stepDisplay() const;
        void playDisplay();
    }
     
    class threadEmetteur : public QThread {
        Q_OBJECT
     
    public:
        void run(QPushButton * button) {
            while(button->isChecked()) {
                msleep(500);
                emit nextStep();
            }
            quit();
        }
     
    signals:
        void nextStep();
    };
    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
     
    tabVisu::tabVisu {
        QPushButton * playBt = nullptr;
        connect(playBt, SIGNAL(clicked()), this, SLOT(playDisplay()));
    }
     
    void tabVisu::playDisplay() {
        threadEmetteur thread;
        connect(&thread, SIGNAL(nextStep()), this, SLOT(stepDisplay()));
        thread.run(playBt);
    }
     
    void tabVisu::stepDisplay() {
        // Affichage sur la carte
    }

  5. #5
    Membre confirmé
    Inscrit en
    Mars 2007
    Messages
    134
    Détails du profil
    Informations forums :
    Inscription : Mars 2007
    Messages : 134
    Par défaut
    Juste une petite correction mais qui ne change rien au résultat:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    void tabVisu::playDisplay() {
        if(playBt->isChecked()) {
            threadEmetteur thread;
            connect(&thread, SIGNAL(nextStep()), this, SLOT(stepDisplay()));
            thread.run(playBt);
        }
    }

  6. #6
    Expert éminent

    Femme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juin 2007
    Messages
    5 202
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Essonne (Île de France)

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

    Informations forums :
    Inscription : Juin 2007
    Messages : 5 202
    Par défaut
    A priori, il ne faut pas bloquer le dessin, mais l'évolution du dessin.
    La boucle de dessin doit se poursuivre (c'est son arrêt qui fige l'interface).

Discussions similaires

  1. Utiliser Application.run avec une classe
    Par baya22 dans le forum VBA Access
    Réponses: 1
    Dernier message: 12/04/2012, 12h07
  2. [Première utilisation] Pas possible de faire un run
    Par Faiche dans le forum Eclipse C & C++
    Réponses: 2
    Dernier message: 30/07/2009, 15h33
  3. web.xml : utilisation de run-at
    Par hihi30 dans le forum Tomcat et TomEE
    Réponses: 0
    Dernier message: 24/11/2008, 12h51
  4. [Virtual Pascal] Comment utiliser linker pour que run fonctionne dans le compilateur
    Par gmaxjeu dans le forum Autres IDE
    Réponses: 1
    Dernier message: 04/07/2008, 20h44
  5. [Erreur] Utilisation du "Run as"
    Par guilopouloos dans le forum Eclipse Java
    Réponses: 3
    Dernier message: 07/02/2007, 10h30

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