0

My application is for drawing shapes (polygons, points ..etc), I used QGrapichView and QGrapichScene and I added two different pixmap items (one for drawing, and the other one is 'legend' that will show the user how much the distance is), So far so good.

I implemented the zoom functionality and it is working fun. Still, my problem is: that when I zoom in/out the whole scene (the canvas QGraphicsPixmapItem and the legend QGraphicsPixmapItem) is affected and that is expected because I am re-scaling the QGrapichView while zooming (using the mouse wheel).

What I want is: I need only the canvas item to be zoomed in/out not the whole scene so that the legend will always be visible to the user.

before zooming in, you can see the legend in the blue text

after zooming in, now you can't see the legend.

Here is a snippet of the code that am using in zooming from this answer:

class PixmapScene(QGraphicsScene):
    pass


class Canvas(QGraphicsView):
    def __init__(self, scene):
        super().__init__(scene)
        self.scene = scene

        self.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
        self.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOff)

        background_color = QColor("#443b36")
        self.pixmap_item: QGraphicsItem = self.scene.addPixmap(QPixmap(780, 580))
        self.pixmap_item.setTransformationMode(Qt.FastTransformation)
        self.pixmap_item.pixmap().fill(background_color)

        self.legend = QPixmap(780, 580)
        self.legend.fill(QColor("#00ffffff"))

        p = QtGui.QPainter(self.legend)
        p.setPen(QPen(QColor("#0000FF"), 4))
        p.drawLine(35 * 5.1, self.legend.height() - 60, 35 * 8.9, self.legend.height() - 60)
        p.setPen(QColor("#c9c9c9"))
        p.setFont(QFont('Century Gothic', 14))
        p.drawText(35 * 5.5, self.legend.height() - 35, f'this text is from the other pixmap (legend)')
        p.end()
        self.scene.addPixmap(self.legend)
        self.zoom_times = 0

   def wheelEvent(self, event):
        zoom_in_factor = 1.25
        zoom_out_factor = 1 / zoom_in_factor

        # Save the scene pos
        old_pos = self.mapToScene(event.pos())

        # Zoom
        if event.angleDelta().y() > 0:
            if self.zoom_times == 6:
                return
            zoom_factor = zoom_in_factor
            self.zoom_times += 1
        else:
            if self.zoom_times == 0:
                return
            zoom_factor = zoom_out_factor
            self.zoom_times -= 1
        # here we are scaling the whole scene, what I want is zooming with keeping legend as it is
        self.scale(zoom_factor, zoom_factor)

        # Get the new position
        new_pos = self.mapToScene(event.pos())
        # Move scene to old position
        delta = new_pos - old_pos
        self.translate(delta.x(), delta.y())
Uncle Bob
  • 155
  • 8
  • please provide a [mre]. I also have the following doubt: I understand that you want to continue showing the legend (which is a rule apparently), but do you want it to scale or maintain a fixed size? – eyllanesc May 17 '22 at 14:00
  • Thanks for your comment, i am making now a code example just needs some time. for now, I just want a maintain fixed size. – Uncle Bob May 17 '22 at 14:16
  • Note: It is always advisable to provide the MRE so do not expect us to ask you for it, do it when publishing your post so we both save time. – eyllanesc May 17 '22 at 14:32
  • it's my bad sorry. – Uncle Bob May 18 '22 at 12:36
  • @eyllanesc Could you help me please if it's possible – Uncle Bob May 19 '22 at 13:28

0 Answers0