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.
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())