텍스트 상자의 위치에 따라 조정되는 줄과 연결된 것으로 가정되는 두 개의 서브 클래 싱 된 QGraphicsRectItem이 있습니다. Qt는의 diagramscene example에서연결된 항목 변경시 사용자 지정 QGraphicsItem의 위치 업데이트
QGraphicsPolygonItem
는 서브 클래스의 메소드 itemChanged
화살표의 위치를 업데이트 setLine
호출 연결된 화살표의 updatePosition
메소드를 호출 도쿠. 내 경우에는 setLine
을 QGraphicsLineItem
대신에 QGraphicsItem
서브 클래 싱으로 호출 할 수 없습니다.
아래의 Arrow
클래스에 updatePosition
메서드를 구현하여 내 QGraphicsItem의 위치를 업데이트하려면 어떻게해야합니까? 다음은 텍스트 상자를 클릭하고 이동할 때 현재 일어나는 일을 보여주는 실행 가능한 예제입니다.
import sys
from PyQt4.QtGui import *
from PyQt4.QtCore import *
class Arrow(QGraphicsItem):
def __init__(self, startItem, endItem, parent=None, scene=None):
super().__init__(parent, scene)
self.startItem = startItem
self.endItem = endItem
def boundingRect(self):
p1 = self.startItem.pos() + self.startItem.rect().center()
p3 = self.endItem.pos() + self.endItem.rect().center()
bounds = p3 - p1
size = QSizeF(abs(bounds.x()), abs(bounds.y()))
return QRectF(p1, size)
def paint(self, painter, option, widget=None):
p1 = self.startItem.pos() + self.startItem.rect().center()
p3 = self.endItem.pos() + self.endItem.rect().center()
pen = QPen()
pen.setWidth(1)
painter.setRenderHint(QPainter.Antialiasing)
if self.isSelected():
pen.setStyle(Qt.DashLine)
else:
pen.setStyle(Qt.SolidLine)
pen.setColor(Qt.black)
painter.setPen(pen)
painter.drawLine(QLineF(p1, p3))
painter.setBrush(Qt.NoBrush)
def updatePosition(self):
#Not sure what to do here...
class TextBox(QGraphicsRectItem):
def __init__(self, text, position, rect=QRectF(0, 0, 200, 100),
parent=None, scene=None):
super().__init__(rect, parent, scene)
self.setFlags(QGraphicsItem.ItemIsFocusable |
QGraphicsItem.ItemIsMovable |
QGraphicsItem.ItemIsSelectable)
self.text = QGraphicsTextItem(text, self)
self.setPos(position)
self.arrows = []
def paint(self, painter, option, widget=None):
painter.setPen(Qt.black)
painter.setRenderHint(QPainter.Antialiasing)
painter.setBrush(Qt.white)
painter.drawRect(self.rect())
def addArrow(self, arrow):
self.arrows.append(arrow)
def itemChange(self, change, value):
if change == QGraphicsItem.ItemPositionChange:
for arrow in self.arrows:
arrow.updatePosition()
return value
if __name__ == "__main__":
app = QApplication(sys.argv)
view = QGraphicsView()
scene = QGraphicsScene()
scene.setSceneRect(0, 0, 500, 1000)
view.setScene(scene)
textbox1 = TextBox("item 1", QPointF(50, 50), scene=scene)
textbox1.setZValue(1)
textbox2 = TextBox("item 2", QPointF(100, 500), scene=scene)
textbox2.setZValue(1)
arrow = Arrow(textbox1, textbox2, scene=scene)
arrow.setZValue(0)
textbox1.addArrow(arrow)
textbox2.addArrow(arrow)
view.show()
sys.exit(app.exec_())
가장 쉬운 방법은'QGraphicsItemGroup' 또는 부모 - 자식 관계를 사용하는 것입니다. 이 두 가지 방법으로 모든 것을 처리하기 때문에 함께 움직이게하기 위해 그 후에 아무 것도 할 필요가 없습니다. – rbaleksandar
나는 모든 항목이 동시에 움직이지만 다른 하나는 움직이지 않는 경우에 대한 제안을 볼 수 있습니다. 그럴까요? – pbreach
나는 그렇게 생각하지 않는다. 기본적으로 연결을 "확장"하지만 선택한 노드 만 이동하려고합니까? 그렇다면 여기를보십시오 (http://www.walletfox.com/course/qgraphicsitemruntimedrawing.php). 기본적으로 원하는대로 마우스를 움직이는 동안 드로잉을 보여줍니다. 노드 중 하나를 움직일 때마다 연결을 다시 만들고 이동 된 노드가 홀로 남을 때까지 업데이트해야합니다.이 경우 노드의 마지막 상태 이동 된 연결이 마지막 연결이됩니다. – rbaleksandar