python - 用于在 librecad 中无限调整大小的绘画的小部件

标签 python pyqt pyqt5 librecad

Librecad 使用一个可以无限调整大小的小部件,您可以尽可能地放大和缩小。它使用哪个小部件?

当我绘制一个常见的小部件时,绘制是在该小部件的某些坐标处完成的。但是,我想在小部件的 float 坐标处进行绘制,并使用固定到视口(viewport)的某些像素的线宽。

调整大小之前:

before resizing:

调整大小后:

after resizing:

哪个小部件提供此功能?

最佳答案

您必须使用 QGraphicsView 和 QGraphicsScene(请参阅 Graphics View Framework ):

from PyQt5 import QtCore, QtGui, QtWidgets


class GraphicsView(QtWidgets.QGraphicsView):
    def __init__(self, parent=None):
        super(GraphicsView, self).__init__(parent)
        self.factor = 1.2

        self.setDragMode(QtWidgets.QGraphicsView.ScrollHandDrag)
        self.setRenderHints(
            QtGui.QPainter.Antialiasing | QtGui.QPainter.SmoothPixmapTransform
        )
        self.setMouseTracking(True)
        self.setScene(
            QtWidgets.QGraphicsScene(QtCore.QRectF(-400, -400, 800, 800), self)
        )

        QtWidgets.QShortcut(QtGui.QKeySequence.ZoomIn, self, activated=self.zoomIn) # Ctrl + +
        QtWidgets.QShortcut(QtGui.QKeySequence.ZoomOut, self, activated=self.zoomOut) # Ctrl + -

    @QtCore.pyqtSlot()
    def zoomIn(self):
        self.zoom(self.factor)

    @QtCore.pyqtSlot()
    def zoomOut(self):
        self.zoom(1 / self.factor)

    def zoom(self, f):
        self.scale(f, f)

    def drawForeground(self, painter, rect):
        super(GraphicsView, self).drawForeground(painter, rect)

        if not hasattr(self, "cursor_position"):
            return
        painter.save()
        painter.setTransform(QtGui.QTransform())
        pen = QtGui.QPen(QtGui.QColor("yellow"))
        pen.setWidth(4)
        painter.setPen(pen)

        r = self.mapFromScene(rect).boundingRect()

        linex = QtCore.QLine(
            r.left(), self.cursor_position.y(), r.right(), self.cursor_position.y(),
        )
        liney = QtCore.QLine(
            self.cursor_position.x(), r.top(), self.cursor_position.x(), r.bottom(),
        )
        for line in (linex, liney):
            painter.drawLine(line)

        painter.restore()

    def mouseMoveEvent(self, event):
        self.cursor_position = event.pos()
        self.scene().update()
        super(GraphicsView, self).mouseMoveEvent(event)

    def wheelEvent(self, event):
        angle = event.angleDelta().y()
        if angle < 0:
            self.zoomIn()
        else:
            self.zoomOut()
        super(GraphicsView, self).wheelEvent(event)


if __name__ == "__main__":
    import sys
    import random

    app = QtWidgets.QApplication(sys.argv)

    w = GraphicsView()

    for _ in range(4):
        r = QtCore.QLineF(
            *random.sample(range(-200, 200), 2), *random.sample(range(50, 150), 2)
        )
        it = w.scene().addLine(r)
        pen = QtGui.QPen(QtGui.QColor(*random.sample(range(255), 3)))
        pen.setWidthF(5.0)
        pen.setCosmetic(True)
        it.setPen(pen)

    w.resize(640, 480)
    w.show()

    sys.exit(app.exec_())

关于python - 用于在 librecad 中无限调整大小的绘画的小部件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59804588/

相关文章:

Python:用特定词提取句子

python - 将图标移动到 QCheckBox 中文本的右侧

Python:对依赖列表进行排序

python - 如何在 Python 中为实例分配属性?

python - 如何通过在python中用单个列表重复相同的元素来无限循环

python - 什么是 "role",它来自哪里? (如何在编辑 QTableView 单元格后更改背景颜色?)

python - 将我选择的颜色附加到 QPieSeries 的每个切片

python-2.7 - 如何清除 pyqt QTableWidget?

python - 在 Windows 7 中安装 PyQt5

python - Pyqt QTablewidget 自动换行