Question

J'ai besoin pour personnaliser le processus de dessin d'un QGraphicsView, et donc je remplacer la méthode drawItems comme ceci:

self.graphicsview.drawItems=self.drawer.drawItems

self.graphicsview est un QGraphicsView et self.drawer est une classe personnalisée avec une méthode drawItems.
Dans cette méthode, je vérifie quelques drapeaux pour décider comment dessiner chaque élément, puis appeler item.paint, comme ceci:

def drawItems(self, painter, items, options):
    for item in items:
        print "Processing", item
        # ... Do checking ...
        item.paint(painter, options, self.target)

self.target est QGraphicsScene du QGraphicsView.
Cependant, une fois qu'il atteint item.paint, il éclate de la boucle - sans aucune erreur. Si je mets conditionals autour de la peinture, et pour chaque type possible de QGraphicsItem coller le code qui est censé être exécuté (en regardant les sources git-Qt), tout fonctionne.
Pas une solution très agréable mais ... Je ne comprends pas comment il pourrait même sortir de la boucle?

Était-ce utile?

La solution

Il y a une exception qui se produit lorsque les éléments sont peints, mais il est pas signalé tout de suite. Sur mon système (PyQt 4.5.1, Python 2.6), pas d'exception est signalée lorsque je singe patch la méthode suivante:

def drawItems(painter, items, options):
    print len(items)
    for idx, i in enumerate(items):
        print idx, i
        if idx > 5:
            raise ValueError()

Sortie:

45
0 <PyQt4.QtGui.QGraphicsPathItem object at 0x3585270>
1 <PyQt4.QtGui.QGraphicsSimpleTextItem object at 0x356ca68>
2 <PyQt4.QtGui.QGraphicsSimpleTextItem object at 0x356ce20>
3 <PyQt4.QtGui.QGraphicsSimpleTextItem object at 0x356cc88>
4 <PyQt4.QtGui.QGraphicsSimpleTextItem object at 0x356cc00>
5 <PyQt4.QtGui.QGraphicsSimpleTextItem object at 0x356caf0>
6 <PyQt4.QtGui.QGraphicsSimpleTextItem object at 0x356cb78>

Cependant, une fois que je ferme l'application, la méthode suivante est imprimée:

Exception ValueError: ValueError() in <module 'threading' from '/usr/lib/python2.6/threading.pyc'> ignored

J'ai essayé l'impression threading.currentThread(), mais il renvoie le même fil que ce soit l'intérieur ou à l'extérieur appelé la méthode drawItems singe-patché.

Dans votre code, cela est probablement dû au fait que vous passez options (qui est une liste d'options de style des objets) aux éléments individuels plutôt que l'objet d'option correspondante. En utilisant ce code devrait vous donner les résultats corrects:

def drawItems(self, painter, items, options):
    for item, option in zip(items, options):
        print "Processing", item
        # ... Do checking ...
        item.paint(painter, option, self.target)

En outre, vous dites que le self.target est l'objet de la scène. Le pour paint() dit:

  

Cette fonction, qui est habituellement appelé par QGraphicsView, peint le contenu d'un élément en coordonnées locales. ... L'argument widget est en option. Si elle est fournie, il pointe le widget qui est peint sur; sinon, il est 0. Pour la peinture en cache, widget est toujours 0.

et le type est QWidget*. QGraphicsScene hérite de QObject et n'est pas un widget, il est donc probable que cela est faux aussi.

Pourtant, le fait que l'exception ne soit pas rapporté du tout, ou pas tout de suite suggère un certain jeu fétide, vous devez contacter le responsable.

Autres conseils

La raison pour laquelle la boucle sort soudainement est qu'une exception est levée. Python ne gère pas (il n'y a pas de bloc try:), il est donc passé à l'appelé (de Qt code C ++) qui n'a aucune idée sur les exceptions de Python, il est donc perdu.

Ajouter un try / except autour de la boucle et vous devriez voir la raison pour laquelle cela se produit.

Remarque:. Depuis Python 2.4, vous ne devriez pas remplacer les méthodes de cette façon plus

Au lieu de cela, vous devez obtenir une nouvelle classe de QGraphicsView et ajoutez votre méthode drawItems() à cette nouvelle classe. Cela remplacera la méthode originale correctement.

Ne pas oublier d'appeler super() dans la méthode __init__! Dans le cas contraire, votre objet ne fonctionnera pas correctement.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top