0

I am making an app that has a graphic scene where you can drag items in and move them in the scene.

I am trying to prevent collusion between items in the scene and saw this question Prohibit collision of a movable QGraphicsItem with other items which didn't work well for me (perhaps because I am using PyQt6 and translated from qt not very well).

I am using QGraphicsEllipseItem and QGraphicsRectItem but every solution for QGraphicsEllipseItem will help very much.

I understood that I need to block movement only on the axis the colliding is occures on but I didn't managed to immplement it. I tried to go through the list of the items the item is colliding with to deal quth multipule collusions.

I am using PyQt6 but anything will help

Here is how I tried to solve it:

from PyQt6.QtWidgets import QApplication, QGraphicsView, QGraphicsScene, QGraphicsEllipseItem, QGraphicsItem
from PyQt6 import QtCore
import typing


class Item(QGraphicsEllipseItem):
    def __init__(self, geo):
        super().__init__(geo)
        self.setFlag(self.GraphicsItemFlag.ItemIsMovable)
        self.setFlag(self.GraphicsItemFlag.ItemSendsGeometryChanges)

    def itemChange(self, change: 'QGraphicsItem.GraphicsItemChange', value: typing.Any) -> typing.Any:
        c = super().itemChange(change, value)
        if change == QGraphicsItem.GraphicsItemChange.ItemPositionChange:
            for collide in self.collidingItems(QtCore.Qt.ItemSelectionMode.IntersectsShape):
                if :#from the right
                    c.setX()#keep on the right
                elif :#from the left
                    c.setX() #keep on the left

                if :#from above
                    c.setY() # keep above
                elif :#from below
                    c.setY() #keep below
        return c


app = QApplication([])
view = QGraphicsView()
s = QGraphicsScene()
s.addItem(Item(QtCore.QRectF(50, 50, 50, 50)))
s.addItem(Item(QtCore.QRectF(200, 200, 50, 50)))
view.setScene(s)
view.show()
app.exec()
  • Depending on the fact that you're using rectangles or ellipses, the solution might change, and *a lot*: collision detection for rectangle is easier, since the shape allows simple adjustments based on the other items' rectangles, but ellipses make it much more complex, as two ellipses might share the same bounding rectangle and still not collide. – musicamante Oct 16 '21 at 17:44
  • The detecting shape is done by pyqt ( using the intersectsShape flag ) but I am trying to adjust the movement – Ron lisnyansky Oct 17 '21 at 06:44
  • No, the detection is based on the *current* position. You need to implement your own detection because you need to check if the *new* position will make your item collide with others and eventually change the result. If you use `collidingItems()` in a `ItemPositionChange`, at that moment the item has not moved yet and you'll get unreliable results. – musicamante Oct 17 '21 at 18:38
  • [This](https://stackoverflow.com/questions/70074528/avoiding-collisions-of-qgraphicsitem-shapes-moved-by-the-mouse) may help you – alec Nov 30 '21 at 03:36

0 Answers0