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.
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.