Issue
I'm trying to constrain this QGraphicsRectItem
's movement by making the origin of the rectangle item follow this QGraphicsLineItem
when moving the rectangle mouse.
Is there any method to do this?
Solution
I got it with a simple implementation, by creating a modified rectangle item and line items:
class Rectangle(QGraphicsRectItem):
def __init__(self, x=0, y=0, w=0, h=0, pathes=[]):
super(Rectangle, self).__init__(x, y, w, h) # x, y are internal object coordinates
self.setTransformOriginPoint(int(w / 2), int(h / 2)) # setting the origin point to the middle
self.origin = self.transformOriginPoint() # returns QPointF
self.setFlag(QGraphicsItem.ItemIsSelectable)
self.setFlag(QGraphicsItem.ItemSendsScenePositionChanges)
self.pathes = pathes
def item_on_path(self, new_point):
new_point = QPointF(new_point.x() + self.origin.x(), new_point.y() + self.origin.y())
for path in self.pathes:
if path.contains(new_point):
return True
return False
class Line(QGraphicsLineItem):
def __init__(self, pt1, pt2):
super(Line, self).__init__(pt1[0], pt1[1], pt2[0], pt2[1])
Then creating the scene object with QShortcut
for keyboard control and setting the scene:
class graphicsViewObject(QGraphicsView):
def __init__(self):
super(graphicsViewObject, self).__init__()
self.scene = QGraphicsScene()
black_pen = QPen(Qt.black)
black_pen.setWidth(5)
self.setScene(self.scene)
self.speed = 10 # keyboard movement change value
pt1 = (200, 200)
pt2 = (800, 200)
self.line_1 = Line(pt1, pt2)
self.line_1.setPen(black_pen)
self.scene.addItem(self.line_1)
self.rect = Rectangle(w=200, h=200, pathes=[self.line_1])
self.rect.setPen(black_pen)
self.rect.setBrush(QBrush(Qt.red))
self.scene.addItem(self.rect)
# Moving the rectangle origin to the first point of the line
self.rect.setPos(QPointF(pt1[0] - self.rect.origin.x(), pt1[1] - self.rect.origin.y()))
QShortcut(Qt.Key_Up, self, self.fooUp)
QShortcut(Qt.Key_Down, self, self.fooDown)
QShortcut(Qt.Key_Left, self, self.fooLeft)
QShortcut(Qt.Key_Right, self, self.fooRight)
def fooUp(self):
for item in self.scene.selectedItems():
pos = item.scenePos()
pos.setY(pos.y() - self.speed)
item_inside_scene = self.scene.sceneRect().contains(item.mapRectToScene(item.boundingRect()))
if item.item_on_path(pos) and item_inside_scene:
item.setPos(pos)
def fooDown(self):
for item in self.scene.selectedItems():
pos = item.scenePos()
pos.setY(pos.y() + self.speed)
item_inside_scene = self.scene.sceneRect().contains(item.mapRectToScene(item.boundingRect()))
if item.item_on_path(pos) and item_inside_scene:
item.setPos(pos)
def fooLeft(self):
for item in self.scene.selectedItems():
pos = item.scenePos()
pos.setX(pos.x() - self.speed)
item_inside_scene = self.scene.sceneRect().contains(item.mapRectToScene(item.boundingRect()))
if item.item_on_path(pos) and item_inside_scene:
item.setPos(pos)
def fooRight(self):
for item in self.scene.selectedItems():
pos = item.scenePos()
pos.setX(pos.x() + self.speed)
item_inside_scene = self.scene.sceneRect().contains(item.mapRectToScene(item.boundingRect()))
if item.item_on_path(pos) and item_inside_scene:
item.setPos(pos)
Answered By - Arsany Samuel
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.