2017-09-24 3 views
0

J'écris une application de simulation d'évolution à l'aide de PyQt4. J'ai des 'créatures' et de la 'végétation' sur une scène QGraphics. Les créatures mangent la végétation, qui rétrécit à mesure qu'elle est mangée, et quand elle descend à une certaine taille, elle meurt et est supprimée de la scène. Les créatures qui meurent de faim sont également supprimées lorsqu'elles meurent.Erreur de segmentation lors de la suppression de QGraphicsItem de la scène

Le problème est, lorsque je supprime les éléments de la végétation de la scène, je reçois une erreur de segmentation (pas tout de suite, il faut une quantité variable de temps). Cela ne s'est pas produit avec les créatures, seulement quand j'ai ajouté la végétation, bien qu'elles soient conceptuellement les mêmes que les créatures (instances de classe).

La boucle spécifique où je supprime les éléments est le suivant (le code est simplifié avec une quantité importante de code remplacé par des commentaires):

dead = set() 
    items = self.scene.items() 
    for item in items: 
     if isinstance(item, Creature): 
      # Do some calculation to specify what creature does 
      for item1 in self.scene.items(): 
       # Look through other items on scene and define interactions 
       if isinstance(item1, Creature): 
        # Specify what to do if current item is being compared to another creature 
       if isinstance(item1, Vegetation): 
        # Specify what to do if current item is being compared to vegetation 
       # If creature dies, add to dead set 
       dead.add(item) 

     elif isinstance(item, Vegetation): 
      # Do same as for creature (see above) 
     # If vegetation dies, add to dead set 
     dead.add(item) 

    # Get rid of all dead items from scene 
    while dead: 
     deadItem = dead.pop() 
     self.scene.removeItem(deadItem) 
     del deadItem 

Si je commente la ligne de self.scene.removeItem, le le programme ne plante pas.

Il semble que le programme appelle une adresse mémoire qui n'est plus valide, mais je ne sais pas ce qui est à l'origine.

L'ensemble de l'application est assez longue, ce qui est la raison pour laquelle je ne l'ai pas mis ici, mais si nécessaire, je peux l'ajouter. J'utilise Python 3.4.3 avec PyQt4 sous Windows. Je suis en train d'utiliser Python 3.4.3 avec PyQt4.

+0

Il ne semble pas judicieux de supprimer des éléments en les parcourant. Ou l'indentation est-elle fausse? – ekhumoro

+0

Je vois de quoi tu parles. J'ai essayé de déplacer cela donc il est en dehors de la boucle 'for item in items', mais le programme plante toujours. –

+0

Je pense que l'indentation est fausse dans votre code posté. – strubbly

Répondre

0

Donc, pour ceux qui ont des problèmes similaires à moi, j'ai trouvé une solution. C'est à voir avec la limite de la végétation et des créatures. Lorsque leur QRectF() est en cours de modification, la scène utilise toujours le précédent boundingRect() avant le changement. Le correctif a été fait en préparant la scène pour mettre à jour la nouvelle QRectF() de chaque élément lorsqu'ils changent, le code pour le faire était:

item.prepareGeometryChange() 

ou

item1.prepareGeometryChange() 

en fonction de l'organisme avait été modifié. Cette ligne (s) de code a été ajoutée juste avant que leur QRectF() ait été changé.

Merci à strubbly de mentionner le boundingRect des éléments.