Bonjour à tous,

nouvel épisode de mon application, j'ai réussi à effectuer un zoom malgré tout mes outils de fonctionne pas tous avec les niveaux de zoom différents de 100%.
Je vous remercie d'avance pour la lecture de mon post ^^ et vos conseils.
J'ai donc une combo box dans ma fênetre principale associée au signal:
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
 def onActivatedComboBox(self,text):        
 
        if text == "300%":
            self.__actionZoom(3)
        if text=="200%":
            self.__actionZoom(2)
        if text == "100%":
            self.__actionZoom(1)
        if text == "75%":
            self.__actionZoom(0.75)
        if text == "50%":
            self.__actionZoom(0.5)
qui appelle l'action zoom qui est en faite celle de la scène ( elle renvoie aussi l'index à mes outils pour connaitre le facteur de zoom).
Puis, dans ma scène, l'action zoom.
GraphicsScene.py
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
  def zoomAction(self, factor ):
        print "zoom : ", factor
 
        #Not rezoom in same factor
        if factor == self.oldFactor:
            pass
        else :
            self.image = self.getCurrentImage()
            w_img, h_img = self.image.width(), self.image.height()
            w, h = w_img * factor, h_img * factor
            self.pixmap = QPixmap().fromImage(self.image.scaled(w, h, 
                                               Qt.KeepAspectRatio, 
                                               Qt.SmoothTransformation))
 
            #Copy of the old one to keep the trace of the items before the zoom
            self.pixItem = PixmapItem(self,self._model)
            self.pixItem.setPixmap(self.pixmap)
 
            self.clear()
            self.addItem(self.pixItem)
            self.pixItem.undoView.hide()
            #Adjusting the size of the scene to the new zooming pixmap
            self.setSceneRect(0, 0, w, h)
            self.oldFactor = factor
Elle recrée pour chaque niveau de zoom un pixItem intégré à la scène.
Sachant que pixmapItem gère les actions. (j'arrive bientôt à mon problème lol)
PixmapItem.py
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
26
27
28
29
30
31
32
33
34
35
36
 
'''
 PixmapItem handles :
     + Mouses events
     + by calling the currentTool set in the Model
'''
class PixmapItem(QGraphicsPixmapItem):
    def __init__(self, scene, model, pixmap=None, parent=None ):
        super(PixmapItem, self).__init__()
        self.scene = scene
        self._model = model
        self.currentTool = None
 
        #Undostack has all the actions to undo/redo shapes
        self.undoStack = QUndoStack()
 
        # Here we can fix the limit of the actions saved
        self.undoStack.setUndoLimit(200)
        '''
        
        TODO:
            + autorub, allows you to rub automatically the color selected from the pixel
            
        '''
        self._createUndoView()
 
    def _createUndoView(self):
        # we give the undoview the stack with all the items to display the actions
        self.undoView = QUndoView(self.undoStack)
        self.undoView.setWindowTitle("Commands list")
        self.undoView.setAttribute(Qt.WA_QuitOnClose,False)
      def mousePressEvent(self, event):
        tool = self._model.currentTool()
          if tool is not None:
                  tool.mousePress(event)
      #etc.. pour move et release
Mon souci est le suivant , j'ai un outil pipette qui fonctione bien avec le zoom,
j'applique seulement le facteur comme ceci .
Code : Sélectionner tout - Visualiser dans une fenêtre à part
color = self.scene().getCurrentImage().pixel(int(x/self.getZoomFactor()), int(y/self.getZoomFactor()))
Je divise les coordonnées par le facteur et cela fonctionne. Mais avec un outil d'effacement d'une couleur, cela ne fonctione pas du tout.
ColorEraserTool
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
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
class ColorEraserTool(AbstractTool):
 
    def __init__(self,*args):
        AbstractTool.__init__(self,*args)
 
        self._model = self.model()
        self.pen = QPen(Qt.SolidLine)
        self.brush = QBrush()
        self.color = QColor()
        self._colorPix = QColor(Qt.white)
        self._name = 'ColorEraserTool'
        self._cursor = QCursor()
        self.x = 0
        self.y = 0
        self._deltaE=0
        self._image = QImage()
        self.pixmap = None
        self.pixmapItem = None
 
        #Allows to get the right color when zoom in Action        
        self._zoomFactor = 1
        #List of the items to put into undostack
        self.items = []
    def getZoomFactor(self):
        return self._zoomFactor
    def setZoomFactor(self,fact):
        self._zoomFactor = fact                   
    def name(self):
        return self._name
 
    def cursor(self):
        _img = QPixmap(2*self._model.width(),2*self._model.width())
        _p = QPainter(_img)
        _p.fillRect(_img.rect(), QBrush(QColor(self._model.foregroundColor())))
        _p.end()
        self._cursor = QCursor(_img,-16,-16)#   
        return self._cursor
 
    def choose(self, p):
        foreColor = QColor(self._model.foregroundColor())
        c_hsv = foreColor.toHsv()
        p_hsv = p.toHsv()
        colorDist =self.color_dist(c_hsv,p_hsv)
        if colorDist < 0.5:
            #print "colorDist",colorDist
            if c_hsv.valueF() !=0 :
                p_hsv.setHsvF(p_hsv.hueF(), 0, min(1.0, p_hsv.valueF() / c_hsv.valueF()))
                return p_hsv.toRgb()
        else:
            return p
 
 
 
    def erase(self, x, y):
        self._colorPix = pc = QColor(self.getImage().pixel(x, y))
        #if pc != Qt.white and self.colorDist() < 20:
        #    return 
        if pc != Qt.white:
            return self.choose(pc)
 
    def applyRubber(self, mx, my):
        w = self._model.width()
        pm = QPixmap(w * 2, w * 2)
        pm.fill(Qt.transparent)
        p = QPainter(pm)
        for x in xrange(-w, w):
            for y in xrange(-w, w):
                #mx,my = int(mx/self.getZoomFactor()), int(my/self.getZoomFactor())
                c = self.erase(mx + x, my + y)
                if c is not None :
                    p.setPen(c)
                    p.drawPoint(x + w, y + w)
        p.end()
        p = QPainter(self.pixmap)
        #mx,my = int(mx * self.getZoomFactor()),int(my * self.getZoomFactor())
        print "Mx , my", mx ,",", my
        p.drawPixmap(mx - w, my - w, pm)
        p.end()
        self.pixmapItem.setPixmap(self.pixmap)
 
    def overlay(self):
        #Creates an overlay on which we 'll apply the rub
        self.pixmap = QPixmap(self.getImage().size())
        self.pixmap.fill(Qt.transparent)
        self.pixmapItem = QGraphicsPixmapItem()
        self.scene().addItem(self.pixmapItem)
        self.items.append(self.pixmapItem)
 
    def getImage(self):
        #Get the image from the scene newly updated
        return self._image
 
    def setImage(self,img):
        self._image= img
 
    def color_dist(self, c1, c2):
        """ returns the squared euklidian distance between two color vectors in hsv space """
        _result = (abs(c1.hueF()-c2.hueF()))**2 + (abs(c1.saturationF() - c2.saturationF()))**2 + (abs(c1.valueF()-c2.valueF()))**2
        return (_result ** 0.5)
 
    def mousePress(self, event):
        self.items = []
        x,y = event.pos().x(), event.pos().y()
        x,y = int(x/self.getZoomFactor()), int(y/self.getZoomFactor())
        self.setImage(self.scene().getCurrentImage())
        self.overlay()
        self.applyRubber(x,y)
 
 
    def mouseMove(self, event):
        x,y = event.pos().x(), event.pos().y()
        x,y = int(x/self.getZoomFactor()), int(y/self.getZoomFactor())
        self.applyRubber(x,y)
        self.scene().update()
 
    def mouseRelease(self, event):
        for i in range(0,len(self.items)):
            addCmd = AddCommand(self.items[i], self.scene(), self.name())
            self.scene().pixItem.undoStack.push(addCmd)
        self.pixmap = None
        self.pixmapItem = None
C'est à dire que la division ne fonctionne pas quand l'index est différent de 1 bien sur, le résultat est que l'image que je souhaite modifier est dessinée à un
autre endroit.
Merci d'avance ^^.