我正在PyQt中编写一个允许用户选择的应用程序
放置在QGraphicsScene
上的图像(使用自定义
QGraphicsPixmapItem
)。选择后,我想要一个旋转手柄
出现在用户可以用鼠标“抓住”的图像上
旋转,从而旋转QGraphicsPixmapItem
。基本上,我在寻找
对于旋转手柄功能,您可以在选择a时进入PowerPoint
形状。这似乎是很多人会做的一个非常基本的功能
已实施,但我在网上找不到任何好的例子。能够
有人指出我正确的方向吗?
答案 0 :(得分:2)
让我们首先将问题分成较小的问题然后再组装一切。我在这个解决方案中使用了PyQt5。
<强> 1。旋转QGraphicsItem
为此,您需要使用项目上的setRotation
设置旋转角度。旋转将围绕setTransformOriginPoint
指定的点。通常一个人会占据一个形状的中心。如果未指定此点,通常会采用形状的左上角。
<强> 2。拖动QGraphicsItem
出于性能原因,QGraphicsItems不可移动,不会向事件框架发送位置更改。通过设置适当的标志QtWidgets.QGraphicsItem.ItemIsMovable | QtWidgets.QGraphicsItem.ItemSendsScenePositionChanges
,您可以更改它。另外QGraphicsItem
不从QObject
继承,因此对于使用信号,我通常还有一个继承自QObject的附加对象。
第3。绘制一个手柄项并确定要旋转的旋转角度
在下面的例子中,我有一个非常小的矩形作为句柄,你当然可以使用你喜欢的任何QGraphicsItem。我的方法make_GraphicsItem_draggable
接受任何QGraphicsItem派生类并使其可拖动。为了确定旋转角度,给定可拖动手柄项目的当前位置和要旋转的项目的变换原点,使用math.atan2
以及这些位置的x
和y
坐标的差异。
示例强>
import math
from PyQt5 import QtCore, QtWidgets
class DraggableGraphicsItemSignaller(QtCore.QObject):
positionChanged = QtCore.pyqtSignal(QtCore.QPointF)
def __init__(self):
super().__init__()
def make_GraphicsItem_draggable(parent):
class DraggableGraphicsItem(parent):
def __init__(self, *args, **kwargs):
"""
By default QGraphicsItems are not movable and also do not emit signals when the position is changed for
performance reasons. We need to turn this on.
"""
parent.__init__(self, *args, **kwargs)
self.parent = parent
self.setFlags(QtWidgets.QGraphicsItem.ItemIsMovable | QtWidgets.QGraphicsItem.ItemSendsScenePositionChanges)
self.signaller = DraggableGraphicsItemSignaller()
def itemChange(self, change, value):
if change == QtWidgets.QGraphicsItem.ItemPositionChange:
self.signaller.positionChanged.emit(value)
return parent.itemChange(self, change, value)
return DraggableGraphicsItem
def rotate_item(position):
item_position = item.transformOriginPoint()
angle = math.atan2(item_position.y() - position.y(), item_position.x() - position.x()) / math.pi * 180 - 45 # -45 because handle item is at upper left border, adjust to your needs
print(angle)
item.setRotation(angle)
DraggableRectItem = make_GraphicsItem_draggable(QtWidgets.QGraphicsRectItem)
app = QtWidgets.QApplication([])
scene = QtWidgets.QGraphicsScene()
item = scene.addRect(0, 0, 100, 100)
item.setTransformOriginPoint(50, 50)
handle_item = DraggableRectItem()
handle_item.signaller.positionChanged.connect(rotate_item)
handle_item.setRect(-40, -40, 20, 20)
scene.addItem(handle_item)
view = QtWidgets.QGraphicsView(scene)
view.setFixedSize(300, 200)
view.show()
app.exec_()
开始(item =大矩形和句柄=小矩形)
拖动手柄后旋转(小矩形)
缺少一件事:手柄与物品位置没有固定的距离(即,不是以圆形移动,而是可以将其拖得更远或更近)。虽然这不会改变旋转角度,但看起来并不完美。但是这里涉及的要点很重要,应该让你走在正确的轨道上。