为了账号安全,请及时绑定邮箱和手机立即绑定

未正确旋转图像

未正确旋转图像

慕尼黑的夜晚无繁华 2023-08-03 17:05:56
我正在尝试旋转 QGraphicsView 对象的背景,但遇到了麻烦。红笔描述了我遇到的问题。我想要的是:我想让箭头保持在屏幕中间的中心位置。我希望背景图像以屏幕中心为参考旋转我想在 QGraphicsView 中定义一个矩形。这将被定义为界定显示内容的区域。因此,每次我旋转屏幕时。图像“未覆盖”的区域始终位于矩形边界之外。我想在屏幕中间定义旋转参考点(x=VIEW_WIDTH/2,y=VIEW_HEIGHT/2)这是我的代码:首先,我将显示箭头类:from PyQt5 import QtCore, QtGui, QtWidgets # importation of some libraries # Construnction of an arrow item, it'll be used in the QGraphicsView class ArrowItem(QtWidgets.QGraphicsPathItem): # it inherit QgraphicsPathItem, which allows to handle it # in the QgraphicsView    def __init__(self, parent=None): # The init method        super().__init__(parent)        self._length = -1        self._angle = 0        self._points = QtCore.QPointF(), QtCore.QPointF(), QtCore.QPointF() # with three points we # construct a triangle.         self.length = 40.0 # the basic triangle length         self.rotate(180) # the triangle was built upside down, though I've just ran the function 'rotate'    @property    def angle(self):        """        angle of the arrow        :return:        """        return self._angle    @angle.setter    def angle(self, angle):        self._angle = angle    @property    def length(self):        return self._length    @length.setter    def length(self, l):        self._length = l        pos_top = QtCore.QPointF(0, l * 4 / 5)        pos_left = QtCore.QPointF(-l * 3 / 5, -l / 5)        pos_right = QtCore.QPointF(            l * 3 / 5,            -l / 5,        )        path = QtGui.QPainterPath()        path.moveTo(pos_top)        path.lineTo(pos_right)        path.lineTo(pos_left)        self.setPath(path)        self._points = pos_top, pos_left, pos_right    def paint(self, painter, option, widget):        pos_top, pos_left, pos_right = self._points        left_color = QtGui.QColor("#cc0000")        right_color = QtGui.QColor("#ff0000")        bottom_color = QtGui.QColor("#661900")
查看完整描述

1 回答

?
慕姐4208626

TA贡献1852条经验 获得超7个赞

如果你想旋转一个QGraphicsItem,没有必要使用QTransform,只需使用setRotation方法即可。另一方面,必须对图像进行缩放,以便与可见区域相交的旋转区域与可见区域相同,并且最小区域计算如下:sqrt(2) x max(width, height)。综合以上情况,解决方案是:


from PyQt5 import QtCore, QtGui, QtWidgets



class ArrowItem(QtWidgets.QGraphicsPathItem):

    def __init__(self, parent=None):

        super().__init__(parent)

        self._length = -1

        self._points = (

            QtCore.QPointF(),

            QtCore.QPointF(),

            QtCore.QPointF(),

        )

        self.length = 40.0


    @property

    def length(self):

        return self._length


    @length.setter

    def length(self, l):

        self._length = l


        pos_top = QtCore.QPointF(0, l * 4 / 5)

        pos_left = QtCore.QPointF(-l * 3 / 5, -l / 5)

        pos_right = QtCore.QPointF(

            l * 3 / 5,

            -l / 5,

        )


        path = QtGui.QPainterPath()

        path.moveTo(pos_top)

        path.lineTo(pos_right)

        path.lineTo(pos_left)


        self.setPath(path)


        self._points = pos_top, pos_left, pos_right


    def paint(self, painter, option, widget):

        pos_top, pos_left, pos_right = self._points


        left_color = QtGui.QColor("#cc0000")

        right_color = QtGui.QColor("#ff0000")

        bottom_color = QtGui.QColor("#661900")


        path_left = QtGui.QPainterPath()

        path_left.lineTo(pos_top)

        path_left.lineTo(pos_left)


        path_right = QtGui.QPainterPath()

        path_right.lineTo(pos_top)

        path_right.lineTo(pos_right)


        path_bottom = QtGui.QPainterPath()

        path_bottom.lineTo(pos_left)

        path_bottom.lineTo(pos_right)


        painter.setPen(QtGui.QColor("black"))

        painter.setBrush(left_color)

        painter.drawPath(path_left)

        painter.setBrush(right_color)

        painter.drawPath(path_right)

        painter.setBrush(bottom_color)

        painter.drawPath(path_bottom)


    def moveTo(self, next_position, duration=100):

        self._animation = QtCore.QVariantAnimation()

        self._animation.setStartValue(self.pos())

        self._animation.setEndValue(next_position)

        self._animation.setDuration(duration)

        self._animation.start(QtCore.QAbstractAnimation.DeleteWhenStopped)

        self._animation.valueChanged.connect(self.setPos)



class MainWindow(QtWidgets.QMainWindow):

    VIEW_HEIGHT = 600

    VIEW_WIDTH = 900


    def __init__(self, parent=None):

        super().__init__(parent)


        self.scene = QtWidgets.QGraphicsScene(self)

        self.view = QtWidgets.QGraphicsView(self.scene)

        self.status_btn = QtWidgets.QPushButton("Status")

        self.settings_btn = QtWidgets.QPushButton("Settings")

        self.analyze_btn = QtWidgets.QPushButton("Analyze")

        self.field_btn = QtWidgets.QPushButton("Field")

        self.guide_btn = QtWidgets.QPushButton("Guide")

        self.mapping_btn = QtWidgets.QPushButton("Mapping")


        central_widget = QtWidgets.QWidget()

        self.setCentralWidget(central_widget)


        vlayl = QtWidgets.QVBoxLayout()

        vlayl.addWidget(self.status_btn)

        vlayl.addWidget(self.settings_btn)

        vlayl.addWidget(self.analyze_btn)


        vlayr = QtWidgets.QVBoxLayout()

        vlayr.addWidget(self.field_btn)

        vlayr.addWidget(self.guide_btn)

        vlayr.addWidget(self.mapping_btn)


        hlay = QtWidgets.QHBoxLayout(central_widget)

        hlay.addLayout(vlayl)

        hlay.addWidget(self.view)

        hlay.addLayout(vlayr)


        self.status_btn.clicked.connect(self.rotate_arrow)

        self.guide_btn.clicked.connect(self.rotate_pixmap)


        self.view.setFixedSize(self.VIEW_WIDTH, self.VIEW_HEIGHT)

        r = self.view.mapToScene(self.view.viewport().rect()).boundingRect()

        self.view.setSceneRect(r)


        factor = 1.5 * max(self.VIEW_WIDTH, self.VIEW_HEIGHT)

        pixmap = QtGui.QPixmap("ola.png").scaled(factor, factor)

        self.pixmap_item = self.scene.addPixmap(pixmap)

        center = self.pixmap_item.boundingRect().center()

        self.pixmap_item.setPos(-center)

        self.pixmap_item.setTransformOriginPoint(center)


        self.arrow_item = ArrowItem()

        self.scene.addItem(self.arrow_item)


    def rotate_arrow(self):

        delta = 30.0

        self.arrow_item.setRotation(self.arrow_item.rotation() + delta)


    def rotate_pixmap(self):

        delta = 15.0


        self.pixmap_item.setRotation(self.pixmap_item.rotation() + delta)

        self.arrow_item.setRotation(self.arrow_item.rotation() + delta)



if __name__ == "__main__":

    import sys


    app = QtWidgets.QApplication(sys.argv)

    w = MainWindow()

    w.show()

    sys.exit(app.exec_())


查看完整回答
反对 回复 2023-08-03
  • 1 回答
  • 0 关注
  • 117 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信