更新连接项更改上自定义QGraphicsItem的位置

2024-09-27 21:31:45 发布

您现在位置:Python中文网/ 问答频道 /正文

我有两个子类qgraphicsrecitem,它们应该与一条根据文本框的位置进行调整的行相连接。在

在Qt文档的diagramscene example中,子类QGraphicsPolygonItemitemChanged方法调用连接箭头的updatePosition方法,该方法调用setLine来更新箭头的位置。在我的例子中,我不能调用setLine,因为我是子类化QGraphicsItem,而不是{}。在

我应该如何在下面的Arrow类中实现updatePosition方法来更新QGraphicsItem的位置?下面是一个可运行的示例,它显示了当前单击和移动文本框时发生的情况。在

enter image description here

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_())

Tags: 方法rectselfnonedefsceneqtpainter
1条回答
网友
1楼 · 发布于 2024-09-27 21:31:45

项目的位置实际上并不重要-它可以保持在0,0-前提是边界框是正确的(它将根据您的Arrow::boundingBox实现)。因此,我认为如果您只需触发一个边界框更改,并在updatePosition中重新绘制,那么一切都将按您的需要工作。在

当然,如果您关心箭头的位置在行的头或尾,您可以在updatePosition中移动它,并相应地调整边界框/绘制坐标-但这完全取决于您是否有意义。在

相关问题 更多 >

    热门问题