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 :

collidingItems() et le processus boucle


Sujet :

Qt

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre averti
    Profil pro
    Inscrit en
    Juillet 2008
    Messages
    16
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2008
    Messages : 16
    Par défaut collidingItems() et le processus boucle
    Bonjour,

    QT 4.7.

    J'ai un QGraphicsPolygonItem, j'ai besoin de compter les autres items graphiques à l'ntérieur, et, jusqu'à ce jour, la fonction

    this->collidingItems()
    fonctionnait sans problème.

    Brutalement, elle a cessé de fonctionner (quel que soit ce qu'il y a à l'intérieur du polygone). Le CPU du process est au maximum et je dois le tuer.

    J'ai du employer un moyen lourd pour remplacer cette fonction (lourd car moins performant), qui est de scanner l'ensemble des items de la scene, et de tester s'il collide avec mon item :

    QList<QGraphicsItem*> dedans = QList<QGraphicsItem*>();
    foreach(QGraphicsItem* item, scene()->items()
    { if ( item->collidesWithItem(this)) dedans<<item; }


    Si quelqu'un sait pourquoi collidingItems() a si mal fonctionné et comment le résoudre, je serais très preneur

  2. #2
    Membre émérite

    Profil pro
    Responsable logiciel
    Inscrit en
    Octobre 2010
    Messages
    224
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : Responsable logiciel

    Informations forums :
    Inscription : Octobre 2010
    Messages : 224
    Par défaut
    Bonjour,

    Je ne sais pas pourquoi collidingItems() a "cessé de fonctionner", ce serait peut être suite à une réimplémentation de shape() dans ta classe ?
    Sinon, tu as aussi la possibilité d'utiliser la version de QGraphicsScene::items(...) qui prend un QPainterPath en paramètre et lui passer shape(), tu aura directement les éléments contenus totalement (ou partiellement suivant la valeur du paramètre "mode") dans ton élément. Et si ça ne marche pas, ça pourrait donner un indice supplémentaire.

  3. #3
    Membre averti
    Profil pro
    Inscrit en
    Juillet 2008
    Messages
    16
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2008
    Messages : 16
    Par défaut
    Citation Envoyé par idiallo Voir le message
    Bonjour,

    Je ne sais pas pourquoi collidingItems() a "cessé de fonctionner", ce serait peut être suite à une réimplémentation de shape() dans ta classe ?
    Non... j'ai du réimplémenter d'autres trucs (comme les pixmap paint pour les scaler) mais pas un simple polygone.

    Citation Envoyé par idiallo Voir le message
    Sinon, tu as aussi la possibilité d'utiliser la version de QGraphicsScene::items(...) qui prend un QPainterPath en paramètre et lui passer shape(), tu aura directement les éléments contenus totalement (ou partiellement suivant la valeur du paramètre "mode") dans ton élément. Et si ça ne marche pas, ça pourrait donner un indice supplémentaire.
    J'avais essayé ça : QGraphicsScene::items(this->polygon()) et il bouclait aussi.
    Je viens d'essayer ton conseil : QGraphicsScene::items(this->shape()) et
    il boucle aussi. Etonnant...
    Merci en tout ca de ton intérêt idiallo !

  4. #4
    Membre émérite

    Profil pro
    Responsable logiciel
    Inscrit en
    Octobre 2010
    Messages
    224
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : Responsable logiciel

    Informations forums :
    Inscription : Octobre 2010
    Messages : 224
    Par défaut
    Il manque du contexte pour analyser de l'extérieur, pour voir si par exemple ton appel peut déclencher une récursion infinie. En supposant que tu ne puisse pas faire du pas à pas, as-tu essayé de mettre des traces, soit sur ton appel, soit dans une réimplémentation de shape() ou contains(), soit directement dans les parties de Qt concernées ?

  5. #5
    Membre averti
    Profil pro
    Inscrit en
    Juillet 2008
    Messages
    16
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2008
    Messages : 16
    Par défaut
    Je ne suis pas avancé pour creuser autant que tu le voudrais...
    Je n'ai jamais réussi à faire tourner mes pgm en mode debug
    Je laisse des traces dans un fichier, ce qui me permet de voir ou ça "plante", etc

    Je n'ai pas réimplémenté shape() ni contains() et me doute que si je les réimplémente, ça risque de ne pas leur faire faire ce qui se doit...
    Le code derrière la fonction "collidingItems" m'est inaccessible...

    Par contre, j'ai de nouvelles observations
    1/
    - collidingItems(Qt::ContainsItemBoundingRect) fonctionne
    - collidingItems(Qt::IntersectsItemBoundingRect) fonctionne
    - collidingItems(Qt::ContainsItemShape) ne fonctionne pas
    - collidingItems(Qt::IntersectsItemShape) ne fonctionne pas
    2/ un autre type d'item (un dérivé de QGraphicsEllipseItem) a le même problème
    3/ j'ai du mal à imaginer comment réimplémenter la fonction shape()
    en faisant en sorte qu'elle fonctionne toujours...
    Dans un simple appel à shape() (pour un objet dont colliding plante) shape() fonctionne en tous cas il ne plante pas.
    mais scene->item(this->shape()) => ne fonctionne pas

    Merci à vous

  6. #6
    Membre émérite

    Profil pro
    Responsable logiciel
    Inscrit en
    Octobre 2010
    Messages
    224
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : Responsable logiciel

    Informations forums :
    Inscription : Octobre 2010
    Messages : 224
    Par défaut
    Citation Envoyé par lepage14 Voir le message
    Je ne suis pas avancé pour creuser autant que tu le voudrais...
    Je n'ai jamais réussi à faire tourner mes pgm en mode debug
    Je laisse des traces dans un fichier, ce qui me permet de voir ou ça "plante", etc

    Je n'ai pas réimplémenté shape() ni contains() et me doute que si je les réimplémente, ça risque de ne pas leur faire faire ce qui se doit...
    Le code derrière la fonction "collidingItems" m'est inaccessible...

    Par contre, j'ai de nouvelles observations
    1/
    - collidingItems(Qt::ContainsItemBoundingRect) fonctionne
    - collidingItems(Qt::IntersectsItemBoundingRect) fonctionne
    - collidingItems(Qt::ContainsItemShape) ne fonctionne pas
    - collidingItems(Qt::IntersectsItemShape) ne fonctionne pas
    2/ un autre type d'item (un dérivé de QGraphicsEllipseItem) a le même problème
    3/ j'ai du mal à imaginer comment réimplémenter la fonction shape()
    en faisant en sorte qu'elle fonctionne toujours...
    L'idée de la réimplémentation, c'était juste pour la trace, par exemple:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    MyItem::shape()
    {
        qDebug("appel de shape");
        return QGraphicsEllipseItem::shape(); 
    }
    ou ça qui pourrait être intéressant aussi vu tes tests:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    MyItem::shape()
    {
        qDebug("appel de shape");
        return QGraphicsEllipseItem::boundingRect(); 
    }
    Citation Envoyé par lepage14 Voir le message
    Dans un simple appel à shape() (pour un objet dont colliding plante) shape() fonctionne en tous cas il ne plante pas.
    mais scene->item(this->shape()) => ne fonctionne pas

    Merci à vous
    Si la "plante" est une série infinie d'appels à shape (par exemple), les traces vont te le montrer.

  7. #7
    Membre averti
    Profil pro
    Inscrit en
    Juillet 2008
    Messages
    16
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2008
    Messages : 16
    Par défaut
    Merci.

    Log intéressant (merci pour le tip) .
    Ce n'est pas shape qui plante ou qui serait appelé N fois. C'est plus profond...

    PS: j'ai testé sur un autre PC (des fois que, comme il arrive qu'on corrompe un PC avec un simple plantage...) avec exactement le même comportement

    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
    QPainterPath DistrictItem::shape()
    {
     
            logger("District - appel de shape en cours");
            QPainterPath path = QGraphicsPolygonItem::shape();
            logger("District - appel de shape fait");
            return path;
    }
    (...) 
    //Utilisation :
    void DistrictItem::showInfo();
    {
    QList<QGraphicsItem*> dedans = QList<QGraphicsItem*>();
     
    QPainterPath path = this->shape();
            logger("shape is working without loop");
            dedans = ww->scene->items(this->shape(), Qt::IntersectsItemShape);// plante
            dedans =        this->collidingItems(); // plante 
     
    // Log:
    20110426 14:14:00 973 District - appel de shape en cours
    20110426 14:14:00 973 District - appel de shape fait
    20110426 14:14:00 973 shape is working without loop
    20110426 14:14:00 973 District - appel de shape en cours
    20110426 14:14:00 973 District - appel de shape fait

  8. #8
    Membre émérite

    Profil pro
    Responsable logiciel
    Inscrit en
    Octobre 2010
    Messages
    224
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : Responsable logiciel

    Informations forums :
    Inscription : Octobre 2010
    Messages : 224
    Par défaut
    Peut être que tu as une boucle dans ta liste de parents, essaie:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    void DistrictItem::showInfo();
    {
       QGraphicsItem *parent = parentItem();
       int compteur = 0;
        while(parent) {
            logger("un parent");
            parent = parent->parentItem();
            compteur ++;
            if(compteur > 1000) {
                logger("boucle dans la liste de parents!");
                break;
            }
        }
    ...

  9. #9
    Membre averti
    Profil pro
    Inscrit en
    Juillet 2008
    Messages
    16
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2008
    Messages : 16
    Par défaut
    Citation Envoyé par idiallo Voir le message
    Peut être que tu as une boucle dans ta liste de parents, essaye (...)
    Merci c'est le genre de chose qui doit arriver et faire des dégats, mais en l'occurence, j'ai testé pour l'ensemble des objets de ma scène (car il y en a beaucoup...)

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    foreach(QGraphicsItem* item ,  scene->items())
        {
            QGraphicsItem *parent = item->parentItem();
            int compteur = 0;
            while(parent) {
                //logger("un parent");
                parent = parent->parentItem();
                compteur ++;
                if(compteur > 1000) {
                    logger(QString("boucle dans la liste de parents pour item type %1").arg(item->type()));
                    break;
                }
            }
        }
    Je suis déçu de ne pas avoir trouvé un seul serpent qui se morde la queue...

    Autre idée: pour des raisons X et Y, j'interromps la descentes des évènements pour certains events de certains objets (mais pas là ou se passe le problème) . J'ai aussi du réimplémenter "otherItem::paint" pour gérer le scale de otherItem, dérivé de QGraphicsPixMapItem.... Je me demande si ça peut jouer et pourquoi....
    PS: comment tracer l'intérieur des fonctions Qt comme colliding ?

    Merci encore idiallo, vraiment sympa toutes tes suggestions

  10. #10
    Membre émérite

    Profil pro
    Responsable logiciel
    Inscrit en
    Octobre 2010
    Messages
    224
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : Responsable logiciel

    Informations forums :
    Inscription : Octobre 2010
    Messages : 224
    Par défaut
    Citation Envoyé par lepage14 Voir le message
    PS: comment tracer l'intérieur des fonctions Qt comme colliding ?
    Normalement, tu as accès au code source de Qt et tu peux le modifier. En fait, le plus efficace est probablement de compiler Qt en mode debug et de faire du pas à pas. Qu'est-ce qui te bloque pour le faire ? Tu es sur quel OS ?

Discussions similaires

  1. Pourquoi mon processus tourne en boucle ?
    Par cladsam dans le forum POSIX
    Réponses: 6
    Dernier message: 09/06/2011, 16h07
  2. Faire tourner un processus dans une boucle infinie
    Par mario002e dans le forum Applications et environnements graphiques
    Réponses: 2
    Dernier message: 19/02/2010, 15h30
  3. Processus en boucle
    Par tiamat59 dans le forum Administration système
    Réponses: 3
    Dernier message: 28/08/2009, 18h24
  4. Probleme de boucle avec des processus sous UNIX
    Par sebastieng dans le forum POSIX
    Réponses: 6
    Dernier message: 15/10/2005, 18h57
  5. Processus en boucle sans fenêtre ni console
    Par alainpeniche dans le forum Threads & Processus
    Réponses: 1
    Dernier message: 26/07/2005, 17h43

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