在QGraphicsScene中连续移动QGraphicSitem并检查碰撞



大约3周前,我要求更改图形学中的图形学。这是一条线,解决方案是:self.setline(..)。现在,我尝试理解,不断地移动它。因此,我有一个GraphicsView GVCanvas,并且在一个场景中,并初始化矩形,行...它起作用

用于移动矩形我具有以下代码,用于使用__init__和MovemyRect

class myRect(QtWidgets.QGraphicsRectItem):
    def __init__(self, QRectF):  # *args):
        QtWidgets.QGraphicsRectItem.__init__(self)
        self.setRect(QRectF)
        self.setFlag(QtWidgets.QGraphicsItem.ItemIsSelectable, True)
        self.setPen(QtGui.QPen(QtCore.Qt.white, 3))
    def movemyRect(self, x, y, angl):
        myyrs = QtWidgets.QGraphicsRectItem.rect(self) #(self.myyr)   #line(items[0])
        ptrr = myyrs.bottomLeft()
        xpos = ptrr.x() + x #+x
        ypos = ptrr.y()  - y
        ptnew=QtCore.QPoint(xpos,ypos)
        myr = QtCore.QRectF(ptnew, QtCore.QSizeF(15,15))
        self.setRotation(angl)
        self.setRect(myr)
        self.update()

然后我尝试围绕rect

移动
    xm =20
    ym = 20
    for i in range(1,5):
        time.sleep(0.8)
        print("nachsleep",i)
        self.rect2.movemyRect(xm, ym, 10)
        myyrs = QtWidgets.QGraphicsRectItem.rect(self.rect2)
        self.rect2.setRect(myyrs)
        self.scene.update()
        listtreffer = self.scene.collidingItems(self.lnk, mode=Qt.IntersectsItemShape)
        for treffer in listtreffer:
            print("treffer", treffer)

循环起作用,但是移动和旋转的矩形出现仅在我场景的循环末端而不是每一步之后都发生了变化。我以为" setRect ..."的说法应该在每次步行循环中工作。scene.update()也无济于事。

如果我没有循环,它也有效。

有什么问题,移动的矩形不会出现在循环中的每个步骤上?

检查碰撞的声明在每个步骤中都正确。

这是一个附加的问题:如果我只想检查此矩形的碰撞,最好在类定义中定义一种碰撞检查,而不是在此循环中?

(我也尝试使用动画和qpropertyanimantion做同样的事情。在那里我无法开火或进行预先宣传。即使移动aroud工作起作用,也要检查碰撞。但是我认为,为此,我应该打开一个新问题)

在GUI中,您永远不应该使用时间。在QT中,您必须使用事件执行操作,例如,每次触发计时器时,请在以下代码中进行更改。为了使流动使用qvariantanimation,由于QgraphicSitem不是qobjects,并且位置不是qproperty。

import random
from functools import partial
from PyQt5 import QtCore, QtGui, QtWidgets
class RectItem(QtWidgets.QGraphicsRectItem):
    def __init__(self, rect=QtCore.QRectF()):
        super(RectItem, self).__init__(rect)
        self.setFlag(QtWidgets.QGraphicsItem.ItemIsSelectable, True)
        self.setFlag(QtWidgets.QGraphicsItem.ItemSendsGeometryChanges, True)
        self.setPen(QtGui.QPen(QtCore.Qt.red, 3))
        self._pos_animation = QtCore.QVariantAnimation()
        self._pos_animation.valueChanged.connect(self.setPos)
    def move_smooth(self, end, duration=1000):
        if self._pos_animation.state() == QtCore.QAbstractAnimation.Running:
            self._pos_animation.stop()
        self._pos_animation.setDuration(duration)
        self._pos_animation.setStartValue(self.pos())
        self._pos_animation.setEndValue(end)
        self._pos_animation.start()
    def itemChange(self, change, value):
        if change ==QtWidgets.QGraphicsItem.ItemPositionChange:
            color = QtGui.QColor(QtCore.Qt.red)
            if self.scene().collidingItems(self):
                color = QtGui.QColor(QtCore.Qt.green)
            self.setPen(QtGui.QPen(color, 3))
        return super(RectItem, self).itemChange(change, value)
def move_pos(scene):
    for it in scene.items():
        pos = QtCore.QPointF(*random.sample(range(-100, 200), 2))
        if hasattr(it, 'move_smooth'):
            it.move_smooth(pos, 1000)
if __name__ == '__main__':
    import sys
    app = QtWidgets.QApplication(sys.argv)
    app.setStyle('fusion')
    scene = QtWidgets.QGraphicsScene(-100, -100, 200, 200)
    scene.setBackgroundBrush(QtCore.Qt.gray)
    view = QtWidgets.QGraphicsView(scene)
    view.resize(640, 480)
    view.show()
    l = []
    for _ in range(4):
        pos = QtCore.QPointF(*random.sample(range(-100, 200), 2))
        it = RectItem(QtCore.QRectF(-20, -20, 40, 40))
        scene.addItem(it)
        it.setPos(pos)
        l.append(it)
    wrapper = partial(move_pos, scene)
    timer = QtCore.QTimer(interval=3000, timeout=wrapper)
    timer.start()
    wrapper()
    sys.exit(app.exec_())

最新更新