如何在PyQT中绘制节点和边?

时间:2010-01-31 20:17:35

标签: python user-interface graph pyqt

在PyQT中,如何在给定点处绘制小“节点”并将其与边缘连接?我找到的所有PyQT教程都是“绘制一个按钮!绘制一个复选框!”

提前非常感谢

2 个答案:

答案 0 :(得分:3)

如果您希望能够与绘图中显示的对象进行交互,最好使用QGraphicsScene。它处理缩放和平移,并且可以包含可以处理自己交互的其他QGraphicsItem个对象。

它非常易于使用,但涉及到一些开销,特别是如果您计划制作数千个对象。

您可以找到PyQt教程here。这个和API文档可以帮助您入门。

答案 1 :(得分:3)

为此找到一个很好的解释是很痛苦的(截至2014年底已经有了),并且由于这个问题直接询问我在寻找什么,我会发布一个转录(从C ++到Python)我在this post找到的内容。

代码如下,这是基本原理:

  1. QGrahpicsItemQPainterPathQPainterPath.Element是您要查找的课程。具体来说,QPainterPath实现了您在CorelDraw,Adobe Illustrator或Inkscape等应用程序中所期望的矢量功能。
  2. 下面的示例受益于预先存在的QGraphicsEllipseItem(用于渲染节点)和QGraphicsPathItem(用于渲染路径本身),它继承自QGraphicsItem
  3. Path构造函数遍历QPainterPath元素,为每个元素创建Node项;反过来,它们中的每一个都会向父Path对象发送更新,从而相应地更新其path属性。
  4. 我发现学习C ++ Qt4 Docs要比在其他地方找到的结构较差的PyQt文档容易得多。一旦习惯了在C ++和Python之间进行心理翻译,文档本身就是学习如何使用每个类的有效方法。

  5. #!/usr/bin/env python
    # coding: utf-8
    
    from PyQt4.QtGui import *
    from PyQt4.QtCore import *
    
    rad = 5
    
    class Node(QGraphicsEllipseItem):
        def __init__(self, path, index):
            super(Node, self).__init__(-rad, -rad, 2*rad, 2*rad)
    
            self.rad = rad
            self.path = path
            self.index = index
    
            self.setZValue(1)
            self.setFlag(QGraphicsItem.ItemIsMovable)
            self.setFlag(QGraphicsItem.ItemSendsGeometryChanges)
            self.setBrush(Qt.green)
    
        def itemChange(self, change, value):
            if change == QGraphicsItem.ItemPositionChange:
                self.path.updateElement(self.index, value.toPointF())
            return QGraphicsEllipseItem.itemChange(self, change, value)
    
    
    class Path(QGraphicsPathItem):
        def __init__(self, path, scene):
            super(Path, self).__init__(path)
            for i in xrange(path.elementCount()):
                node = Node(self, i)
                node.setPos(QPointF(path.elementAt(i)))
                scene.addItem(node)
            self.setPen(QPen(Qt.red, 1.75))        
    
        def updateElement(self, index, pos):
            path.setElementPositionAt(index, pos.x(), pos.y())
            self.setPath(path)
    
    
    if __name__ == "__main__":
    
        app = QApplication([])
    
        path = QPainterPath()
        path.moveTo(0,0)
        path.cubicTo(-30, 70, 35, 115, 100, 100);
        path.lineTo(200, 100);
        path.cubicTo(200, 30, 150, -35, 60, -30);
    
        scene = QGraphicsScene()
        scene.addItem(Path(path, scene))
    
        view = QGraphicsView(scene)
        view.setRenderHint(QPainter.Antialiasing)
        view.resize(600, 400)
        view.show()
        app.exec_()