PyQt5 QGraphicsPixmapItem旋转中心

问题描述

我正在尝试使用PyQt5和Qt Designer创建一个简单的速度计。由于速度计箭头self.arrow的旋转,我遇到了问题。
这是代码:

class MyWin(QtWidgets.QMainWindow):
    def __init__(self,parent=None):
        QtWidgets.QWidget.__init__(self,parent)
        self.ui = Ui_MainWindow()
        self.ui.setupUi(self)

        self.ui.speedSlider.valueChanged.connect(self.valuechange)

        scene = QGraphicsScene()
        scene.setSceneRect(0,self.width(),self.height())
        self.pixmap = QPixmap(":/img/img/speed_arrow.png")
        self.arrow = scene.addPixmap(self.pixmap)

        graphicsView = QGraphicsView(scene,self.ui.centralwidget)
        graphicsView.setStyleSheet( "background-image:url(:/img/img/central1.png);\n"
                                    "background-repeat:no-repeat;\n"
                                    "background-position: center;\n"
                                    "\n"
                                    "border:none;")
        self.ui.gridLayout.addWidget(graphicsView)

    def valuechange(self):
        angel = self.ui.speedSlider.value()
        xform = QTransform()
        xform.rotate(angel)
        xformed_pixmap = self.pixmap.transformed(xform,Qt.SmoothTransformation)
        self.arrow.setPixmap(xformed_pixmap)

        #print(self.arrow.sceneBoundingRect())

我没有在代码本身中绘制速度计箭头,而是加载了一个

picture

我还添加了一个滑块self.ui.speedSlider,用于确定旋转角度。

当我移动滑块时,实际上实现了箭头的旋转。问题在于箭头没有绕其中心旋转。

Example

如何固定旋转中心使其始终位于箭头self.arrow的中心?

这是Ui_MainWindow代码:

class Ui_MainWindow(object):
    def setupUi(self,MainWindow):
        MainWindow.setObjectName("MainWindow")
        MainWindow.resize(800,600)
        MainWindow.setStyleSheet("background-image:url(:/img/img/bgd.png);\n"
"possition:center;")
        self.centralwidget = QtWidgets.QWidget(MainWindow)
        self.centralwidget.setObjectName("centralwidget")
        self.gridLayout = QtWidgets.QGridLayout(self.centralwidget)
        self.gridLayout.setObjectName("gridLayout")
        self.speedSlider = QtWidgets.QSlider(self.centralwidget)
        self.speedSlider.setMaximum(99)
        self.speedSlider.setOrientation(QtCore.Qt.Horizontal)
        self.speedSlider.setObjectName("speedSlider")
        self.gridLayout.addWidget(self.speedSlider,1,1)
        MainWindow.setCentralWidget(self.centralwidget)
        self.menubar = QtWidgets.QMenuBar(MainWindow)
        self.menubar.setGeometry(QtCore.QRect(0,800,21))
        self.menubar.setObjectName("menubar")
        MainWindow.setMenuBar(self.menubar)
        self.statusbar = QtWidgets.QStatusBar(MainWindow)
        self.statusbar.setObjectName("statusbar")
        MainWindow.setStatusBar(self.statusbar)

        self.retranslateUi(MainWindow)
        QtCore.QMetaObject.connectSlotsByName(MainWindow)

    def retranslateUi(self,MainWindow):
        _translate = QtCore.QCoreApplication.translate
        MainWindow.setWindowTitle(_translate("MainWindow","MainWindow"))

箭头

Central1

解决方法

只要值改变,就不要变换像素图。变换像素图发生在本地像素图坐标系中,只会使事情复杂化。

相反,将旋转设置为self.arrow

  1. 使用self.arrow.setTransformOriginPoint()将旋转原点设置为针底的中心(因此几乎是像素图的宽度,而其高度的一半)。创建箭头后立即执行此操作。
  2. 只要值更改,就使用self.arrow.setRotation()。它将使箭头项绕其起点(即针的底部)旋转。

有关here的QGraphicsItems转换的更多信息。

相关问答

错误1:Request method ‘DELETE‘ not supported 错误还原:...
错误1:启动docker镜像时报错:Error response from daemon:...
错误1:private field ‘xxx‘ is never assigned 按Alt...
报错如下,通过源不能下载,最后警告pip需升级版本 Requirem...