放大和缩小小部件

Pep*_*o33 2 python pyqt python-3.x pyqt5

如何使用小部件上的按键输入制作缩放效果?该小部件位于滚动区域内,并且有一些使用 QPainter 绘制的绘图会随着用户输入而变化。缩放会影响滚动条的长度,距离越近,滚动条越小。最小级别的缩放应该使滚动条与小部件区域一样大,这样小部件中的所有内容都可以可视化。

雷:

from PyQt5 import QtCore, QtWidgets
from PyQt5.QtWidgets import QWidget
from PyQt5.QtCore import Qt
from PyQt5.QtGui import QPainter, QPen, QColor
import sys


class Diedrico(QWidget):
    def __init__(self, parent):
        super().__init__(parent)

    def paintEvent(self, event):
        qp = QPainter(self)
        qp.setPen(QPen(QColor(Qt.black), 5))
        qp.drawRect(500, 500, 1000, 1000)


class UiVentana(QtWidgets.QMainWindow):
    def __init__(self, parent=None):
        super(UiVentana, self).__init__(parent)
        self.resize(520, 520)
        self.widget_central = QtWidgets.QWidget(self)
        scrol = QtWidgets.QScrollArea(self.widget_central)
        scrol.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOn)
        scrol.setGeometry(QtCore.QRect(10, 10, 500, 500))
        scrol.setWidgetResizable(False)

        contenido = QtWidgets.QWidget()
        contenido.setGeometry(QtCore.QRect(0, 0, 2000, 2000))
        scrol.setWidget(contenido)

        self.Diedrico = Diedrico(contenido)
        self.Diedrico.setGeometry(QtCore.QRect(0, 0, 2000, 2000))
        self.setCentralWidget(self.widget_central)


if __name__ == "__main__":
    app = QtWidgets.QApplication(sys.argv)
    ui = UiVentana()
    ui.show()
    sys.exit(app.exec_())
Run Code Online (Sandbox Code Playgroud)

eyl*_*esc 6

为什么要重新发明轮子?与其想要实现缩放功能的逻辑,不如使用已经实现的类。在这种情况下,一个不错的选择是将 QGraphicsView 与 QGraphicsScene 一起使用:

注意:快捷方式标准 Zoom In 和 Zoom Out 分别与Ctrl++Ctrl+相关联-

from PyQt5 import QtCore, QtGui, QtWidgets


class Diedrico(QtWidgets.QWidget):
    def paintEvent(self, event):
        qp = QtGui.QPainter(self)
        pen = QtGui.QPen(QtGui.QColor(QtCore.Qt.black), 5)
        qp.setPen(pen)
        qp.drawRect(500, 500, 1000, 1000)


class UiVentana(QtWidgets.QMainWindow):
    factor = 1.5

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

        self._scene = QtWidgets.QGraphicsScene(self)
        self._view = QtWidgets.QGraphicsView(self._scene)

        self._diedrico = Diedrico()
        self._diedrico.setFixedSize(2000, 2000)
        self._scene.addWidget(self._diedrico)

        self.setCentralWidget(self._view)

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

        QtWidgets.QShortcut(
            QtGui.QKeySequence(QtGui.QKeySequence.ZoomOut),
            self._view,
            context=QtCore.Qt.WidgetShortcut,
            activated=self.zoom_out,
        )

    @QtCore.pyqtSlot()
    def zoom_in(self):
        scale_tr = QtGui.QTransform()
        scale_tr.scale(UiVentana.factor, UiVentana.factor)

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

    @QtCore.pyqtSlot()
    def zoom_out(self):
        scale_tr = QtGui.QTransform()
        scale_tr.scale(UiVentana.factor, UiVentana.factor)

        scale_inverted, invertible = scale_tr.inverted()

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


if __name__ == "__main__":
    import sys

    app = QtWidgets.QApplication(sys.argv)
    ui = UiVentana()
    ui.show()
    sys.exit(app.exec_())
Run Code Online (Sandbox Code Playgroud)

更新:

如果要分别使用+-用于 ZoomIn 和 ZoomOut,则只需将快捷方式更改为:

QtWidgets.QShortcut(
    QtGui.QKeySequence(QtCore.Qt.Key_Plus), # <---
    self._view,
    context=QtCore.Qt.WidgetShortcut,
    activated=self.zoom_in,
)

QtWidgets.QShortcut(
    QtGui.QKeySequence(QtCore.Qt.Key_Minus), # <---
    self._view,
    context=QtCore.Qt.WidgetShortcut,
    activated=self.zoom_out,
)
Run Code Online (Sandbox Code Playgroud)