python - PySide 节点图连接项

标签 python pyside

此代码的目的是节点图类型的 UI。 双击创建矩形,右键单击将它们与线连接。如果您在矩形上移动,相应的线尾也会随之移动。问题是该线仅随着前两个矩形移动。如果您创建另一对矩形并用线连接它们,它将停止移动。我最近开始学习PySide/PyQt,所以可能我不理解所有代码。

代码如下: https://github.com/cyberiRex/irex/blob/master/nodeGraph

最佳答案

生成此错误的代码如下:

self.selectedItems()[0].linkToItem = item
self.selectedItems()[1].linkToItem = item

假设一个节点已经通过链接连接到另一个节点,当添加另一个链接时,前一个链接将被删除,这就是它们断开连接的原因。

这样的逻辑会继续产生类似的错误,所以我提出的解决方案是一个新的解决方案逻辑,为此我基于以下示例 Elastic Nodes Example 。从你可以作为理解我的解决方案逻辑的基础来看,显然我做了一些变体来满足你的要求。

在第一部分中,我将基类替换为 QGraphicsRectItem 和 QGraphicsLineItem 以减少实现。该逻辑基于提供它们连接到的每个 Edge 2 节点,以便在更新时将其作为节点的引用。此外,每个节点都存储一个边列表,以便每次移动节点时都会执行更新。下面的代码实现了上述内容:

class SceneClass(QGraphicsScene):
    grid = 30

    def __init__(self, parent=None):
        QGraphicsScene.__init__(self, QRectF(-1000, -1000, 2000, 2000), parent)

    def drawBackground(self, painter, rect):
        painter.fillRect(rect, QColor(30, 30, 30))
        left = int(rect.left()) - int((rect.left()) % self.grid)
        top = int(rect.top()) - int((rect.top()) % self.grid)
        right = int(rect.right())
        bottom = int(rect.bottom())
        lines = []
        for x in range(left, right, self.grid):
            lines.append(QLine(x, top, x, bottom))
        for y in range(top, bottom, self.grid):
            lines.append(QLine(left, y, right, y))
        painter.setPen(QPen(QColor(50, 50, 50)))
        painter.drawLines(lines)

    def mouseDoubleClickEvent(self, event):
        node = Node()
        self.addItem(node)
        node.setPos(event.scenePos())
        QGraphicsScene.mouseMoveEvent(self, event)

    def mousePressEvent(self, event):
        if event.button() == Qt.RightButton:
            if len(self.selectedItems()) == 2:
                edge = Edge(self.selectedItems()[0], self.selectedItems()[1])
                self.addItem(edge)
        QGraphicsScene.mousePressEvent(self, event)


class Node(QGraphicsRectItem):
    def __init__(self, rect=QRectF(-75, -15, 150, 30), parent=None):
        QGraphicsRectItem.__init__(self, rect, parent)
        self.edges = []
        self.setZValue(1)
        self.setBrush(Qt.darkGray)
        self.setFlags(QGraphicsItem.ItemIsMovable |
                      QGraphicsItem.ItemIsSelectable |
                      QGraphicsItem.ItemSendsGeometryChanges)

    def addEdge(self, edge):
        self.edges.append(edge)

    def itemChange(self, change, value):
        if change == QGraphicsItem.ItemSelectedChange:
            self.setBrush(Qt.green if value else Qt.darkGray)

        if change == QGraphicsItem.ItemPositionHasChanged:
            for edge in self.edges:
                edge.adjust()

        return QGraphicsItem.itemChange(self, change, value)


class Edge(QGraphicsLineItem):
    def __init__(self, source, dest, parent=None):
        QGraphicsLineItem.__init__(self, parent)
        self.source = source
        self.dest = dest
        self.source.addEdge(self)
        self.dest.addEdge(self)
        self.setPen(QPen(Qt.red, 1.75))
        self.adjust()

    def adjust(self):
        self.prepareGeometryChange()
        self.setLine(QLineF(self.dest.pos(), self.source.pos()))

获取如下图所示:

enter image description here

完整的示例可以在下面的 link 中找到。

关于python - PySide 节点图连接项,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46142167/

相关文章:

python - 如何使用python将图像插入特定的excel文件单元格?

python - QFile 无法打开包含 unicode 字符的文件名

python - OS X + Qt : How to capture all key-press events in the entire GUI?

python - Google Drive drive.files.get API 经常出现 HTTP 500 内部错误

python - AWS 产品 API : what is the correct regional location and url for us west 2

Python 二进制乘法。分而治之

python - 在 matplotlib 中使用 fill 或 fill_between 绘制 donut

python - 通过python编译PySide资源

python - pyqt 信号发出对象实例或无

python - 使用 QWebView 请求的 POST 请求