title: Simplifying a QPainterPath to an outline
body: <p>I'm creating a custom drawing application using a <code>QGraphicsScene</code> in PySide - I want to be able to draw complex shapes and have the user interact with them via mouse. To accomplish this I created a custom <code>QGraphicsItem</code> called <code>Node</code> that defines its shape by returning a <code>QPainterPath</code> object. The graphics scene uses this shape to decide when the mouse has entered the object. In the objects <code>paint</code> method I simply draw the path using a <code>QPainter</code>.</p>
  
  <pre><code>import math
  import sys
  import weakref
  from numpy import *
  from PySide.QtGui import *
  from PySide.QtCore import *
  
  
  class Node(QGraphicsItem):
      Type = QGraphicsItem.UserType+1
  
      def __init__(self, graphWidget, line):
  
          super(self.__class__, self).__init__()
          self.line = line
          self.graph = weakref.ref(graphWidget)
          self.setFlag(QGraphicsItem.ItemIsMovable)
          self.newPos = QPointF()
          self.setZValue(-1)
  
      def boundingRect(self):
          adjust = 10.0
          return QRectF(self.line[0][0]-adjust, self.line[0][1]-adjust, 2*adjust + self.line[1][0]-self.line[0][0]+100,2*adjust+self.line[1][2]-self.line[0][3]+100)
  
      def shape(self):
          (x0,y0), (xn,yn) = p0, pn = self.line
          dx,dy = xn-x0, yn-y0
          dV = array([dx,dy])
          mag_dV = linalg.norm(dV)
          radius = 10
          rotation = array( [[0,-1],[1,0]])
  
          v = dot(rotation, dV) * radius / mag_dV
  
          startAngle = arctan2(*v) * 180/pi + 90
  
  
          path = QPainterPath()
          path.setFillRule(Qt.WindingFill)
          path.moveTo(*p0 - v)
          path.addEllipse( x0-radius, y0-radius, 2*radius, 2*radius)
          path.moveTo(*p0+v)
  
          path.lineTo( QPoint(*pn+v))
  
          path.arcTo( xn - radius, yn-radius, 2*radius, 2*radius, startAngle+180, 180)
  
  
          path.lineTo(QPoint(*p0-v))
  
          return path.simplified()
  
      def paint(self, painter, option, widget):
          painter.setPen(QPen(Qt.black))
          painter.setBrush(Qt.darkGray)
          painter.drawPath(self.shape())
  
  
  class GraphWidget(QGraphicsView):
      def __init__(self):
          super(self.__class__, self).__init__()
  
          self.timerId = 0
  
          scene = QGraphicsScene(self)
          scene.setItemIndexMethod(QGraphicsScene.NoIndex)
          scene.setSceneRect(-200,-200,400,400)
          self.setScene(scene)
          self.setCacheMode(QGraphicsView.CacheBackground)
          self.setRenderHint(QPainter.Antialiasing)
  
          self.centerNode = Node(self, [[-100,-100],[0,-70]])
          scene.addItem(self.centerNode)
  
          self.centerNode.setPos(0,0)
          self.scale(0.8,0.8)
          self.setMinimumSize(400,400)
          self.setWindowTitle(self.tr("Elastic Nodes"))
  
  
  
  if __name__ == "__main__":
      app = QApplication(sys.argv)
      qsrand(QTime(0,0,0).secsTo(QTime.currentTime()))
  
      widget = GraphWidget()
      widget.show()
  
      sys.exit(app.exec_())
  </code></pre>
  
  <p>The issue I have is how to make the polygon into one solid shape. An example shape is this rectangle with rounded ends:</p>
  
  <p><img src="https://i.stack.imgur.com/6NG1R.png" alt="desired drawing"></p>
  
  <p>When I draw the rounded end with an ellipse instead of an arc, I get this:</p>
  
  <p><img src="https://i.stack.imgur.com/NmEPa.png" alt="actual drawing with inner paths showing and alternating fill"></p>
  
  <p>What I want to achieve is that the paths contained inside the shape of the polygon are gone and all I have is an outline of the entire shape, filled with a solid color. I also want to get rid of the alternating fill that you see. This would ostensibly allow me to create arbitrary polygons without calculating every exact angle and intersection point.</p>
  
  <p>What I have tried so far:</p>
  
  <p>The first thing I tried was to use <code>path.setFillRule(Qt.WindingFill)</code>, which is supposed to make all inner spaces filled as opposed to having alternating color. This doesn't seem to do anything to change the outcome however.</p>
  
  <p>The second thing I tried was use 'path.simplified()', which is supposed to do precisely what I am asking. The results of this command are:</p>
  
  <p><img src="https://i.stack.imgur.com/bgRyZ.png" alt="inner paths after running &lt;code&gt;path.simplified()&lt;/code&gt;"></p>
  
  <p>How can I overcome this problem?</p>