简体   繁体   中英

Pyqt5 - Zoom on a QLabel

I'm trying to apply a zoom example that I've found on this site but it uses a QGraphicsScene and a QGraphicsView while I should use a simple QLabel. This is the code but it does not work. Can I zoom on a Qlabel or is it impossible? The zoom should work with ctrl++ / ctrl+- shortcut.

from PyQt5 import QtCore, QtGui, QtWidgets
from PyQt5.QtWidgets import QLabel
class GuiZoom(QtWidgets.QMainWindow):
   factor = 1.5

   def __init__(self, parent=None):
       super(GuiZoom, self).__init__(parent)

   
       self.setFixedSize(800, 600)

    
       self.lblZoom = QLabel("Facciamo lo zoom")
       self.lblZoom.setStyleSheet("border:10px solid green")
    
       self.setCentralWidget(self.lblZoom)

       QtWidgets.QShortcut(
           QtGui.QKeySequence(QtGui.QKeySequence.ZoomIn),
           self.lblZoom,
           context=QtCore.Qt.WidgetShortcut,
           activated=self.zoom_in,
       )

       QtWidgets.QShortcut(
           QtGui.QKeySequence(QtGui.QKeySequence.ZoomOut),
           self.lblZoom,
           context=QtCore.Qt.WidgetShortcut,
           activated=self.zoom_out,
       )
   def zoom_in(self):
       scale_tr = QtGui.QTransform()
       scale_tr.scale(GuiZoom.factor, GuiZoom.factor)

       tr = self.lblZoom.transform() * scale_tr
       self.lblZoom.setTransform(tr)

   def zoom_out(self):
       scale_tr = QtGui.QTransform()
       scale_tr.scale(GuiZoom.factor, GuiZoom.factor)

       scale_inverted, invertible = scale_tr.inverted()

      if invertible:
           tr = self.lblZoom.transform() * scale_inverted
           self.lblZoom.setTransform(tr)


if __name__ == "__main__":
   import sys

   app = QtWidgets.QApplication(sys.argv)
   ui = GuiZoom()
   ui.show()
   sys.exit(app.exec_())

Moreover can you explain me what the last lines of zoom_out functions do? Is this a way to invert the zoom?

One possible solution is to use a QGraphicsEffect to scale the QLabel's painting.

Note: The size of the widget is not changed but the painting is scaled.

from PyQt5 import QtCore, QtGui, QtWidgets


class ZoomEffect(QtWidgets.QGraphicsEffect):
    factor = 1.5
    _scale = 1.0

    @property
    def scale(self):
        return self._scale

    @scale.setter
    def scale(self, scale):
        self._scale = scale
        self.update()

    def draw(self, painter):
        painter.setRenderHints(
            QtGui.QPainter.Antialiasing
            | QtGui.QPainter.SmoothPixmapTransform
            | QtGui.QPainter.HighQualityAntialiasing
        )
        center = self.sourceBoundingRect(QtCore.Qt.DeviceCoordinates).center()

        pixmap, offset = self.sourcePixmap(QtCore.Qt.DeviceCoordinates)
        painter.setWorldTransform(QtGui.QTransform())

        painter.translate(center)
        painter.scale(self.scale, self.scale)
        painter.translate(-center)

        painter.drawPixmap(offset, pixmap)

    def zoom_in(self):
        self.scale *= self.factor

    def zoom_out(self):
        self.scale /= self.factor


class GuiZoom(QtWidgets.QMainWindow):
    def __init__(self, parent=None):
        super(GuiZoom, self).__init__(parent)

        self.setFixedSize(800, 600)

        self.lblZoom = QtWidgets.QLabel("Facciamo lo zoom")
        self.lblZoom.setStyleSheet("border:10px solid green")

        self.zoom_effect = ZoomEffect()
        self.lblZoom.setGraphicsEffect(self.zoom_effect)

        self.setCentralWidget(self.lblZoom)

        QtWidgets.QShortcut(
            QtGui.QKeySequence(QtGui.QKeySequence.ZoomIn),
            self.lblZoom,
            context=QtCore.Qt.WindowShortcut,
            activated=self.zoom_effect.zoom_in,
        )

        QtWidgets.QShortcut(
            QtGui.QKeySequence(QtGui.QKeySequence.ZoomOut),
            self.lblZoom,
            context=QtCore.Qt.WindowShortcut,
            activated=self.zoom_effect.zoom_out,
        )


if __name__ == "__main__":
    import sys

    app = QtWidgets.QApplication(sys.argv)
    ui = GuiZoom()
    ui.show()
    sys.exit(app.exec_())

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM