2017-08-11 9 views
0

ノードを作成して相互に接続しようとしています。私はsetElementPositionAtに積み重なっています。エラーは: AttributeError: 'PySide.QtGui.QPainterPath' object has no attribute 'updateElement' 私はここに作業コードを見つけました:How can I draw nodes and edges in PyQT?しかし、私のウィジェットにそれを適応させることはできません。 私は間違っていますか?あなたは、コードを理解していない場合は、エラーを持っていることが通常であるので、あなたが基準としている基底クラスに変更を加えたPySide/PyQt4ドローノードと接続

from PySide.QtCore import * 
from PySide.QtGui import * 

rad = 5 


class WindowClass(QMainWindow): 
    def __init__(self): 
     super(WindowClass, self).__init__() 
     self.view = ViewClass() 
     self.setCentralWidget(self.view) 


class ViewClass(QGraphicsView): 
    def __init__(self): 
     super(ViewClass, self).__init__() 

     self.setDragMode(QGraphicsView.RubberBandDrag) 
     self.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff) 
     self.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOff) 

     self.s = SceneClass() 
     self.setScene(self.s) 
     self.setRenderHint(QPainter.Antialiasing) 


class SceneClass(QGraphicsScene): 
    def __init__(self, id=None): 
     super(SceneClass, self).__init__() 
     self.setSceneRect(-1000, -1000, 2000, 2000) 
     self.grid = 30 

     self.p = QPainterPath() 
     self.it = None 
     self.node = None 

    def drawBackground(self, painter, rect): 
     if False: 
      painter = QPainter() 
      rect = QRect() 

     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 mousePressEvent(self, event): 
     if event.button() == Qt.RightButton: 
      self.p.moveTo(0, 0) 
      self.p.lineTo(200, 100) 
      self.it = Path(self.p,None) 
      self.addItem(self.it) 
      for i in xrange(2): 
       self.node = Node(self, i, QPointF(self.p.elementAt(i))) 
       self.node.setPos(QPointF(self.p.elementAt(i))) 
       self.addItem(self.node) 

     super(SceneClass, self).mousePressEvent(event) 


class Path(QGraphicsPathItem): 
    def __init__(self, path, scene): 
     super(Path, self).__init__(path) 
     self.pth = path 

     self.scn = SceneClass(self.setPen(QPen(Qt.red, 1.75))) 

    def updateElement(self, index, pos): 
     print pos 
     self.pth.setElementPositionAt(index, pos.x(), pos.y()) 
     self.pth.setPath(self) 


class Node(QGraphicsEllipseItem): 
    def __init__(self, path, index, pos): 
     super(Node, self).__init__(-rad, -rad, 2*rad, 2*rad) 

     self.pos = pos 
     self.rad = rad 
     self.path = QPainterPath() 
     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) 
     return QGraphicsEllipseItem.itemChange(self, change, value) 

if __name__ == '__main__': 
    app = QApplication([]) 
    wd = WindowClass() 
    wd.show() 
    app.exec_() 
+0

あなたはmousePressEvent方法で行うには何をしたいですか? – eyllanesc

答えて

2

: は、ここでは、コードです。

updateElementメソッドを呼び出すときは、クラスQPaintePathのインスタンスではなく、Pathクラスのインスタンスから行う必要があります。最初に参照したのと同じコードを配置して追加しましたあなたのグラフィック部分に。

class WindowClass(QMainWindow): 
    def __init__(self): 
     super(WindowClass, self).__init__() 
     self.view = ViewClass() 
     self.setCentralWidget(self.view) 


class ViewClass(QGraphicsView): 
    def __init__(self): 
     super(ViewClass, self).__init__() 

     self.setDragMode(QGraphicsView.RubberBandDrag) 
     self.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff) 
     self.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOff) 

     self.s = SceneClass() 
     self.setScene(self.s) 
     self.setRenderHint(QPainter.Antialiasing) 


class SceneClass(QGraphicsScene): 
    def __init__(self, id=None): 
     super(SceneClass, self).__init__() 
     self.setSceneRect(-1000, -1000, 2000, 2000) 
     self.grid = 30 
     self.it = None 
     self.node = None 

    def drawBackground(self, painter, rect): 
     if False: 
      painter = QPainter() 
      rect = QRect() 

     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 mousePressEvent(self, event): 
     if event.button() == Qt.RightButton: 
      path = QPainterPath() 
      path.moveTo(0, 0) 
      path.lineTo(200, 100) 
      self.addItem(Path(path, self)) 
     super(SceneClass, self).mousePressEvent(event) 

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) 
     return QGraphicsEllipseItem.itemChange(self, change, value) 


class Path(QGraphicsPathItem): 
    def __init__(self, path, scene): 
     super(Path, self).__init__(path) 
     for i in range(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 = self.path() 
     path.setElementPositionAt(index, pos.x(), pos.y()) 
     self.setPath(path) 

enter image description here

+0

私のエラーがどこにあったのかは明らかです。ただ一つの質問。変数 'change'はどのように機能しますか? 'self.path.updateElement(self.index、value)'を実行すると意味します。その変数の型を出力すると、別のオブジェクトのリストが得られます。 'setElementPositionAt'を実行するとインデックスと' pos.x()とpos.y() 'が必要なので、' updateElement() 'が' QPointF() 'リストからどのように取得されるのですか? – iRex

+0

もう一つの質問: 'SceneClass'のアイテム? 'self.selectedItems()'は選択された要素に関する情報を提供しません。 – iRex

+0

docs: 'setElementPositionAt()'を見れば、アイテムのインデックスを受け取ってx座標とy座標の座標になりますが、QPointFは直接一致しませんが、関数x )とy() – eyllanesc