2010-01-31 38 views
10

En PyQT, ¿cómo puedo trazar pequeños "Nodos" en puntos determinados y conectarlos con los bordes? Todos los tutoriales de PyQT que encuentro son "¡Trace un botón! ¡Trace una casilla de verificación!"¿Cómo puedo dibujar nodos y bordes en PyQT?

Enormes gracias de antemano

Respuesta

3

Si usted quiere ser capaz de interactuar con los objetos que se muestran en la trama, que será mejor usar un QGraphicsScene. Maneja el zoom y la panorámica y puede contener otros objetos QGraphicsItem que pueden manejar sus propias interacciones.

Es muy fácil de usar, pero implica un poco de sobrecarga, especialmente si planea fabricar miles de objetos.

Puede encontrar un tutorial de PyQt here. Esto y los documentos de API deberían ayudarte a comenzar.

+0

que no sabemos sobre el tutorial que ha vinculado a. Obtengo un error de segmentación cada vez que cierro la aplicación PyQt. – rbaleksandar

+0

El tutorial es de 2008, por lo que algunas cosas podrían haber cambiado mientras tanto. Segfault-on-close suele ser una señal de que algo anda mal con la duración/configuración de las clases de QT básicas (QApplication, QMainWindow, etc.). Si puede ejecutar tutoriales para su versión de PyQt, debería poder incorporar los elementos necesarios para que QGraphicsScene funcione. – drxzcl

+0

He solucionado mis problemas. Pero sí, la versión es vieja. – rbaleksandar

3

Ha sido un dolor encontrar una buena explicación para esto (a partir de finales de 2014), y como esta pregunta pregunta exactamente qué estaba buscando, publicaré una transcripción (de C++ a Python) de lo que encontré en this post.

El código está por debajo, y aquí está la razón de ser:

  1. QGrahpicsItem, QPainterPath y QPainterPath.Element son las clases que está buscando. Específicamente, QPainterPath implementa el tipo de funcionalidad vectorial que espera en aplicaciones como CorelDraw, Adobe Illustrator o Inkscape.
  2. El ejemplo siguiente se beneficia del QGraphicsEllipseItem preexistente (para nodos de representación) y QGraphicsPathItem (para representar la ruta en sí), que hereda de QGraphicsItem.
  3. El constructor Path itera sobre los elementos QPainterPath, creando Node elementos para cada uno; Cada uno de ellos, a su vez, envía actualizaciones al objeto de ruta padre, que actualiza su propiedad path en consecuencia.
  4. Encontré mucho, mucho más fácil estudiar los documentos C++ Qt4 que los documentos PyQt bastante menos estructurados que se encuentran en otros lugares. Una vez que te acostumbras a traducir mentalmente entre C++ y Python, los documentos son una forma poderosa de aprender a usar cada clase.

#!/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_() 
+0

¡Este código me ha ayudado mucho últimamente! ¡Gracias! También estoy tratando de trazar una función en el nodo de la clase - mousePressEvent/click central para agregar un punto de control a la ruta lineA.() Para que desde el punto A> BI pueda agregar el punto C en el medio ... así puedo hacer un " L "forma ... significado> A/B arriba izquierda/derecha abajo y C es esquina ... Pero no estoy seguro de si es el camino correcto ya que no detecto los círculos rojos de la línea de dibujo cuando presiono ... ¿Alguna pista de cómo puedo hacerlo? ¡Gracias! – Dariusz

+1

@Dariusz Estoy seguro de que hay algún tipo de evento o bandera "mouseover" incorporado en Qt, pero no recuerdo su nombre, ni más ni menos qué clase lo tiene. Comenzaría a buscar eso en 'QGraphicsItem'. – heltonbiker

+1

@Dariusz, de hecho los encontré, son los 'hoverEnterEvent' y' hoverLeaveEvent', encontrados [aquí] (http://doc.qt.io/qt-4.8/qgraphicsitem.html). – heltonbiker

Cuestiones relacionadas