PySide 节点图连接项 [英] PySide Node Graph connect items

查看:55
本文介绍了PySide 节点图连接项的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

代码如下:

可以在以下链接中找到完整示例一个>

The purpose of this code is node graph kind of UI. Double click creates rectangles and right click connects them with line. If you move on of the rectangle the corresponding end of line moves with it. The problem is that the line moves only with first two rectangles. If you create another pair of rectangles and connect them with line it stops moving. I have started to learn PySide/PyQt recently so maybe I don't understand all code.

Here is the code: https://github.com/cyberiRex/irex/blob/master/nodeGraph

解决方案

The Code that generates this error is the following one:

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

Let's say that one node is already connected to another by a link, when another link is added, the previous link is removed, which is why they are disconnected.

The logic like this will continue generating similar errors so the solution I propose is a new solution logic, for this I base on the following example Elastic Nodes Example. From what you can take as a basis to understand the logic of my solution, obviously I have made some variants to meet your requirements.

In a first part I have replaced the base classes to QGraphicsRectItem and QGraphicsLineItem to reduce implementation. The logic is based on giving each Edge 2 Node to which they connect so that when it is updated take as reference to the nodes. in addition each node stores a list of the edges so that it executes the update every time the node is moved. The following code implements the above:

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

Obtaining what is shown in the following image:

The complete example can be found in the following link

这篇关于PySide 节点图连接项的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆