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

Qt Discussion :

Trop de signaux, comment limiter leur appel ?


Sujet :

Qt

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre très actif Avatar de Matthieu76
    Homme Profil pro
    Consultant informatique
    Inscrit en
    Mars 2013
    Messages
    568
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Hauts de Seine (Île de France)

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

    Informations forums :
    Inscription : Mars 2013
    Messages : 568
    Par défaut Trop de signaux, comment limiter leur appel ?
    Bonjour, j'ai un algorithme qui tourne dans un QtConcurrent::run et avec un SIGNAL l'affiche sur ma MainWindow le nombre d'itération. Jusqu'à là tout va bien mais le problème c'est que des fois mon algo fait 1 ou 2 itérations par seconde et des fois 1000 itérations par seconde et à ce moment ça fait laguer tout mon programme. Comment faire pour limiter le nombre de d' emit de mon SIGNAL ? En gros je voudrais ne récupérer qu'un emit toutes les 200 ms et pas à chaque fois que j'envoie un signal quand il y en a trop.

    Es-ce que changer l'argument Qt::ConnectionType de ma Qt::connect pourrais aider ? (en gros éviter de remplir la queue si c'est le même SIGNAL)

  2. #2
    Membre très actif Avatar de Matthieu76
    Homme Profil pro
    Consultant informatique
    Inscrit en
    Mars 2013
    Messages
    568
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Hauts de Seine (Île de France)

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

    Informations forums :
    Inscription : Mars 2013
    Messages : 568
    Par défaut SOLUTION
    Sinon je peux toujours créer une variable clock() et envoyer le SIGNAL seulement si le dernier envoie date de plus de 200ms et comme ça j'aurais la fluidité de l'affichage mais sans le lag. Ou encore mieux, directement utiliser un QTimer pour faire un rafraîchissement toues les 200ms même si l'itération en cours n'est pas fini, on ré-affichera juste le même nombre dans ce cas. Vous en pensez quoi ?

  3. #3
    Expert éminent
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 644
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 644
    Par défaut
    Salut,

    Tous les widgets -- non, excuses moi -- toutes les classes qui dérivent de QObject on dispose d'une fonction blockSignals(bool).

    Si tu invoque cette fonction avec la valeur true comme paramètre sur un de tes widgets, tous ses signaux seront bloqué, jusqu'à ce que tu ré-invoques cette fonction avec la valeur false.

    Tu n'as donc absolument pas besoin d'un QTimer (qui prendrait -- en plus, du temps pour travailler) ni quoi que ce soit... un simple
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    void MonWidgetQuiEnvoieTropDeSignaux::foo(){
        blockSignals(true);
        /* toute la logique qui aurait nécessité l'envoi de signaux */
        blockSignals(false);
        /* il faudra sans doute quand même émettre un signal quelconque à la fin, pour qu'il soit émis au moins une fois :D */
    }
    devrait donc suffire
    A méditer: La solution la plus simple est toujours la moins compliquée
    Ce qui se conçoit bien s'énonce clairement, et les mots pour le dire vous viennent aisément. Nicolas Boileau
    Compiler Gcc sous windows avec MinGW
    Coder efficacement en C++ : dans les bacs le 17 février 2014
    mon tout nouveau blog

  4. #4
    Membre très actif Avatar de Matthieu76
    Homme Profil pro
    Consultant informatique
    Inscrit en
    Mars 2013
    Messages
    568
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Hauts de Seine (Île de France)

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

    Informations forums :
    Inscription : Mars 2013
    Messages : 568
    Par défaut
    Merci pour ta réponse mais ta solution ne fonctionne pas car si je savais quand faire un blockSignals(true) je n'en aurais pas besoin, je n'enverrai juste pas de signal à ce moment et c'est tout.

    Il me faudrait plutôt un truc du genre :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    void MainWindow::leSlotDeMonSignal() {
        MonWidgetQuiEnvoieTropDeSignaux.blockSignals(true);
        // Ici je rafraîchis mon interface
        MonWidgetQuiEnvoieTropDeSignaux.blockSignals(false);
     
    }
    Comme ça je ne peux pas recevoir de signal tant que je n'ai pas fini de traiter le dernier que j'ai reçu.
    Mais je ne suis pas sur que cela ne fasse pas quand même lagger mon programme.

    Au final je pense qu'utiliser un timer est le seul moyen de savoir s'il y a trop de signal ou non.
    Du coup j'ai opté pour un QTimer qui refresh ma valeur pendant ma phase de calcul toutes les 250 ms.
    De plus, le QTimer ne me prendrait pas de temps pour travailler car il ne s'exécute pas sur le même thread (enfin si un peu en vrai faudrait que je run mon algo sur un cœur different de mon CPU pour être sûr que ma GUI n'interfère absolument pas dans mon temps de calcul).

  5. #5
    Expert éminent
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 644
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 644
    Par défaut
    Et pourquoi ne pourrais tu pas bloquer ton signal le temps de tout mettre en place, avant de le débloquer et d'envoyer un signal de mise à jour global

    Ta seule obligation est de séparer clairement la logique qui enverra (sans doute) trop de signaux et celle qu'il s'occupera d'envoyer le signal de mise à jour global. Mais ca, ce n'est jamais que le respect du SRP dans sa plus simple acceptation

    Car, qu'il n'y ait qu'un seul signal émis et que ton programme tourne "correctement" ou qu'il y en ait 150, et que ton programme commence à lagger, tu te fous pas mal de savoir combien de signaux seront émis!!! Tout ce que tu veux, c'est qu'il y en ait le moins possible!

    Et, le moins possible, c'est généralement égal à ... 0!!! Allez, 1 pour quand meme provoquer l'affichage

    Garde les choses simples!!! (KISS !!!): C'est simple de bloquer et de débloquer des signaux! C'est simple d'envoyer un signal particulier une fois que tout le travail a été effectué!

    C'est en tout cas beaucoup plus simple que de commencer à se casser la tête pour déterminer si le nombre de signaux émis en une durée donnée risque ou non de commencer à faire lagger ton programme

    Maintenant, si tu tiens à jouer avec un QTimer, tu peux toujours t'amuser un peu et faire en sorte de bloquer les signaux juste avant la mise en route de ton timer, et de les débloquer quand "le délais est écoulé". Mais ca devient quand même beaucoup plus compliqué malgré tout.

    Et si tu veux tout savoir, sache que j'ai eu à trouver une solution similaire sur un QGraphicsView dont la mise à jour de QGraphicsItem provoquait le raffraichissement et finissait par faire lagger le reste.

    Il a suffit qu'on bloque les signaux pour résoudre le problème. Je ne te propose donc pas une solution simplement "tirée de mon chapeau", mais bel et bien une solution qui a été éprouvée sur un projet très important et professionnel
    A méditer: La solution la plus simple est toujours la moins compliquée
    Ce qui se conçoit bien s'énonce clairement, et les mots pour le dire vous viennent aisément. Nicolas Boileau
    Compiler Gcc sous windows avec MinGW
    Coder efficacement en C++ : dans les bacs le 17 février 2014
    mon tout nouveau blog

  6. #6
    Membre très actif Avatar de Matthieu76
    Homme Profil pro
    Consultant informatique
    Inscrit en
    Mars 2013
    Messages
    568
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Hauts de Seine (Île de France)

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

    Informations forums :
    Inscription : Mars 2013
    Messages : 568
    Par défaut
    Citation Envoyé par koala01 Voir le message
    Et pourquoi ne pourrais tu pas bloquer ton signal le temps de tout mettre en place, avant de le débloquer et d'envoyer un signal de mise à jour global
    Et bien j'ai une boucle while et dedans j'ai itérations qui prennent 1 seconde et d'autre 1 ms (j'ai fortement simplifier mais en gros c'est ça). Du coup je ne sais pas quand bloqué ou non les signaux. Je pense vraiment que la solution la meilleur et la plus simple est de rafraîchir mon interface à intervalle régulier, de plus j'utilise ce QTimer pour afficher un timer pour savoir combien de temps prends mon algo à s’exécuter.

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

Discussions similaires

  1. Réponses: 10
    Dernier message: 23/06/2007, 16h13
  2. Comment connaitre l'appelant d'une méthode
    Par Alec6 dans le forum API standards et tierces
    Réponses: 5
    Dernier message: 12/07/2004, 14h51
  3. [C#] Comment limiter l'accès à certaines personnes ?
    Par moimoimoi dans le forum Services Web
    Réponses: 1
    Dernier message: 26/05/2004, 10h14
  4. [VB.NET] Comment faire un appel de fonction ?
    Par Webman dans le forum ASP.NET
    Réponses: 4
    Dernier message: 18/05/2004, 10h06
  5. Comment limiter les mouvements du curseur??
    Par scorpiwolf dans le forum C++Builder
    Réponses: 9
    Dernier message: 07/07/2002, 22h09

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