0

I am trying to use the QGraphicsItemGroup class to constrain a group of objects to move by the same amount in one (e.g. the vertical) direction as shown in the diagram below, where the vertical movement of the item B (shown by a red arrow) is shared by items A, C and D, but not its horizontal movement (which is shown by the blue arrows). See also the code below:

enter image description here

import sys
from PySide2.QtCore     import Qt
from PySide2.QtGui      import QBrush
from PySide2.QtWidgets  import QApplication , QGraphicsScene , QGraphicsView , QGraphicsItem , QGraphicsItemGroup , QGraphicsEllipseItem

if __name__=="__main__":
    app = QApplication(sys.argv)

    graphicsView = QGraphicsView()
    graphicsView.setSceneRect( -50 , -50 , 300 , 100 )
    scene = QGraphicsScene(graphicsView)
    graphicsView.setScene(scene)

    graphicsItemGrp = QGraphicsItemGroup()
    graphicsItemGrp.setFlag( QGraphicsItem.ItemIsMovable )
    graphicsItemGrp.setHandlesChildEvents( False )

    brush = QBrush( Qt.black )

    item1 = QGraphicsEllipseItem( 0 , 0 , 20 , 20 )
    item1.setFlag(QGraphicsItem.ItemIsMovable)
    item1.setCursor( Qt.SizeAllCursor )
    item1.setBrush( brush )

    item2 = QGraphicsEllipseItem( 50 , 0 , 20 , 20 )
    item2.setFlag(QGraphicsItem.ItemIsMovable)
    item2.setCursor( Qt.SizeAllCursor )
    item2.setBrush( brush )

    item3 = QGraphicsEllipseItem( 100 , 0 , 20 , 20 )
    item3.setFlag(QGraphicsItem.ItemIsMovable)
    item3.setCursor( Qt.SizeAllCursor )
    item3.setBrush( brush )

    item4 = QGraphicsEllipseItem( 150 , 0 , 20 , 20 )
    item4.setFlag(QGraphicsItem.ItemIsMovable)
    item4.setCursor( Qt.SizeAllCursor )
    item4.setBrush( brush )


    graphicsItemGrp.addToGroup( item1 )
    graphicsItemGrp.addToGroup( item2 )
    graphicsItemGrp.addToGroup( item3 )
    graphicsItemGrp.addToGroup( item4 )
    scene.addItem( graphicsItemGrp )

    graphicsView.show()
    sys.exit(app.exec_())

I am not certain that QGraphicsItemGroup is the way to go but its the most promising approach that I've been able to find.

A QGraphicsItemGroup is a special type of compound item that treats itself and all its children as one item (i.e., all events and geometries for all children are merged together). It's common to use item groups in presentation tools, when the user wants to group several smaller items into one big item in order to simplify moving and copying of items.

Source Qt 5.13 docs

Olumide
  • 5,397
  • 10
  • 55
  • 104
  • In my case with PySide2 5.13.1 on Linux with your current code it works correctly – eyllanesc Sep 14 '19 at 15:13
  • I've just upgraded PySide2 to version 2.13.1 (from 2.12.?) and I don't see any difference. Offsets to one for are not shared by other dots. As I said I want the dots to share offsets in the Y direction but not the X direction, and there is nothing in the code that ensures this. – Olumide Sep 16 '19 at 07:24
  • With your current code in my tests I see that it is shared in all directions. I think I misunderstood your question, do you want them to share only the vertical movement and not in the horizontal direction? – eyllanesc Sep 16 '19 at 07:30
  • @eyllanesc Yes. – Olumide Sep 16 '19 at 09:44
  • @eyllanesc I have a solution. It relies on `QGraphicsItem.itemChange` and breaks the Qt's recommendation not to call `setPos` in `QGraphicsItem.itemChange` (or appears to) but it solves this problem as well as a [related question](https://stackoverflow.com/questions/56768301/using-qt-model-view-framework-to-notify-qgraphicsitem-in-a-view-of-user-edit-mad) that I posed 2 months ago (still unanswered). – Olumide Sep 16 '19 at 20:50
  • I'm reluctant to post my solution because I don't want to give bad advise. – Olumide Sep 16 '19 at 21:00

0 Answers0