1

I'm happy of QGraphicsItem.ItemIsMovable to move a QGraphicsRectItem() with the mouse. If the Control Key is pressed down, I would like it to move only vertically = keep mouse the position x() a fixed value. To keep it simple, below code doesn't show the use of 'Control Key'

My idea is to inherit QGraphicsScene(), overload mouseMoveEvent(), change event.pos().x() to a fixed value, and call super() with modified event.

import sys
from PyQt5.QtWidgets import *

class QGraphicsScene(QGraphicsScene):
    def mouseMoveEvent(self, event):
        newEvent = event
       #newEvent.setPos(  100.0, event.pos().y() ) #### HERE, I need help ! !
        super().mouseMoveEvent(newEvent)

class MainWindow(QWidget):
    def __init__(self ):
        super(QWidget, self).__init__()

        self.scene = QGraphicsScene()
        self.scene.setSceneRect( 0.0, 0.0, 640.0, 480.0 )

        view= QGraphicsView()
        view.setScene(self.scene)
        layout = QVBoxLayout()
        layout.addWidget( view )
        self.setLayout( layout )

        self.myRect= QGraphicsRectItem( 0,  0, 100, 100)
        self.scene.addItem( self.myRect )

        self.myRect.setFlag( QGraphicsItem.ItemIsMovable,      True  )

if __name__ == "__main__":
    app = QApplication(sys.argv)
    window = MainWindow()
    window.show()
    app.exec_()

If I will un-comment the line 7 :

    newEvent.setPos(  100.0, event.pos().y() )

I will have this error :

AttributeError: 'QGraphicsSceneMouseEvent' object has no attribute 'setPos'

How can I do ? Thanks.

jljPatch
  • 23
  • 6

1 Answers1

-1

Item movements can be restricted by setting the ItemSendsGeometryChanges flag and by implementing their itemChange() and checking for changes of type ItemPositionChange, which are sent before the item is moved:

class VerticallyBlockedRect(QGraphicsRectItem):
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.setFlag(self.GraphicsItemFlag.ItemSendsGeometryChanges)

    def itemChange(self, change, value):
        if change == self.GraphicsItemChange.ItemPositionChange:
            value.setY(self.y())
        return super().itemChange(change, value)

You will obviously need to implement the above in order to prevent the movement only when required.

musicamante
  • 41,230
  • 6
  • 33
  • 58