Python 在QGraphicsItem上添加动画时遇到的一个问题
我想在QGraphicsItem上使用QPropertyImation,希望rect项可以从点(100,30)移动到点(100,90)。但是为什么矩形会在窗口的右侧移动呢?x坐标100应使矩形根据场景大小在中间移动 这是我的密码:Python 在QGraphicsItem上添加动画时遇到的一个问题,python,pyqt,pyqt5,Python,Pyqt,Pyqt5,我想在QGraphicsItem上使用QPropertyImation,希望rect项可以从点(100,30)移动到点(100,90)。但是为什么矩形会在窗口的右侧移动呢?x坐标100应使矩形根据场景大小在中间移动 这是我的密码: import sys from PyQt5.QtCore import QPropertyAnimation, QPointF, QRectF from PyQt5.QtWidgets import QApplication, QGraphicsEllipseItem
import sys
from PyQt5.QtCore import QPropertyAnimation, QPointF, QRectF
from PyQt5.QtWidgets import QApplication, QGraphicsEllipseItem, QGraphicsScene, QGraphicsView, \
QGraphicsObject
class CustomRect(QGraphicsObject):
def __init__(self):
super(CustomRect, self).__init__()
def boundingRect(self):
return QRectF(100, 30, 100, 30)
def paint(self, painter, styles, widget=None):
painter.drawRect(self.boundingRect())
class Demo(QGraphicsView):
def __init__(self):
super(Demo, self).__init__()
self.resize(300, 300)
self.scene = QGraphicsScene()
self.scene.setSceneRect(0, 0, 300, 300)
self.rect = CustomRect()
self.ellipse = QGraphicsEllipseItem()
self.ellipse.setRect(100, 180, 100, 50)
self.scene.addItem(self.rect)
self.scene.addItem(self.ellipse)
self.setScene(self.scene)
self.animation = QPropertyAnimation(self.rect, b'pos')
self.animation.setDuration(1000)
self.animation.setStartValue(QPointF(100, 30))
self.animation.setEndValue(QPointF(100, 90))
self.animation.setLoopCount(-1)
self.animation.start()
if __name__ == '__main__':
app = QApplication(sys.argv)
demo = Demo()
demo.show()
sys.exit(app.exec_())
任何帮助都将不胜感激。试试:
import sys
from PyQt5.QtCore import QPropertyAnimation, QPointF, QRectF
from PyQt5.QtWidgets import QApplication, QGraphicsEllipseItem, QGraphicsScene, QGraphicsView, \
QGraphicsObject
class CustomRect(QGraphicsObject):
def __init__(self):
super(CustomRect, self).__init__()
def boundingRect(self):
# return QRectF(100, 30, 100, 30)
return QRectF(0, 0, 100, 30) # +++
def paint(self, painter, styles, widget=None):
painter.drawRect(self.boundingRect())
class Demo(QGraphicsView):
def __init__(self):
super(Demo, self).__init__()
self.resize(300, 300)
self.scene = QGraphicsScene()
self.scene.setSceneRect(0, 0, 300, 300)
self.rect = CustomRect()
self.ellipse = QGraphicsEllipseItem()
self.ellipse.setRect(100, 180, 100, 50)
self.scene.addItem(self.rect)
self.scene.addItem(self.ellipse)
self.setScene(self.scene)
self.animation = QPropertyAnimation(self.rect, b'pos')
self.animation.setDuration(3000)
self.animation.setStartValue(QPointF(100, 30))
self.animation.setEndValue(QPointF(100, 90))
self.animation.setLoopCount(-1)
self.animation.start()
if __name__ == '__main__':
app = QApplication(sys.argv)
demo = Demo()
demo.show()
sys.exit(app.exec_())
看来他们不知道地球的不同坐标系 在该系统中,至少有以下坐标系:
- 窗口(viewport())的坐标系,其中(0,0)始终位于窗口的左上角
- 场景的坐标系,这是相对于某个预先建立的点
- 每个项目的坐标系,该坐标系由paint()方法用于绘制,boundingRect()和shape()方法用于获取项目的边
- QGraphicsView就是摄像机的屏幕
- QGraphicscene是记录的场景,因此点(0,0)是一些方便的点 <> LQ>是场景的元素,它们的位置可以相对于其他项目或场景,例如,我们可以考虑演员的鞋相对于演员的位置,或者项目可以是同一演员。
基于以上,我将解释发生了什么,我们将给出几个解决方案
rect项没有父项,默认情况下,项的位置图标为(0,0),因此此时项的坐标系与场景重合,因此boundingRect将直观地定义位置,并且当您放置QRectF(100,30,100,30)时,将在该位置绘制,该位置在场景中重合相同。但是,当应用动画时,首先要做的是将项目的位置设置为(100,30),这样,由于场景和项目的坐标系不匹配,一个从另一个移动,因此boundingRect不再匹配场景的QRectF(100,30,100,30),而是以相同的因子移动(仅因为存在位移,所以没有缩放或旋转),矩形将为QRectF(200、60、100、30),并且相对于始终在QRect中的椭圆(100、180、100、50)矩形从200>100开始在右边,从60开始向上谢谢@eyllanesc,你的回答和往常一样好。那么你的意思是动画是基于项目的坐标而不是场景的坐标吗?我实际上知道如何解决这个问题,但就是不理解动画使用的坐标。@很高兴我没有这么说,我所做的是什么所说的是视觉观察是一组变换的结果。我想,为了简化事物,必然的结论必须总是从(0,0)开始。因为这是相对于同一项目的坐标系的,因为这避免了复杂的计算,这在我的第一个解决方案中很明显。@很高兴动画不知道或对了解不同类型的坐标系感兴趣,它只修改属性“pos”。在本例中,pos是关于场景的,但您的项目绘制在一个矩形上,该矩形已在自身上移位
QRectF(100,30,100,30)
,and@just_be_happy[cont.]您还可以将其相对于场景移动:QPointF(100,30)在动画结束后的一段时间内,图形从QRectF+(100,30)移动(100,30)QPoint的值=(200,60),因此它位于椭圆(100,180,100,50)的右侧和上方。只需始终使用QRectF(0,0,w,h)实现boundingRect并使用setPos移动它。我认为如果boundingRect是(100,30,100,30),并且如果我想让rect在右侧移动,我需要使用QPointF(200,30)和QPointF(200,90)。我不知道有位移。谢谢你。我会把你的答案标记为正确。但为什么会有位移?