PySideを使用してカスタム描画アプリケーションを作成してQGraphicsScene
います。複雑な形状を描画し、ユーザーがマウスで操作できるようにしたいと考えています。これを実現するために、オブジェクトを返すことで形状を定義するカスタムQGraphicsItem
コールを作成しました。グラフィックス シーンは、この形状を使用して、マウスがオブジェクトに入ったタイミングを決定します。オブジェクトメソッドでは、. を使用してパスを描画するだけです。Node
QPainterPath
paint
QPainter
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_())
私が抱えている問題は、ポリゴンを1つのソリッドシェイプにする方法です。形状の例は、端が丸い次の長方形です。
円弧ではなく楕円で丸みを帯びた端を描くと、次のようになります。
私が達成したいのは、多角形の形状内に含まれるパスがなくなり、形状全体の輪郭が単色で塗りつぶされていることだけです。また、表示される交互の塗りつぶしを取り除きたいと思います。これにより、正確な角度と交点をすべて計算することなく、任意のポリゴンを作成できるようになります。
私がこれまでに試したこと:
私が最初に試したのは、 を使用することでしたpath.setFillRule(Qt.WindingFill)
。これは、色が交互になるのではなく、すべての内部空間を塗りつぶすことになっています。ただし、これは結果を変えるために何もしていないようです。
私が試した2番目のことは、私が求めていることを正確に行うはずの「path.simplified()」を使用することでした。このコマンドの結果は次のとおりです。
どうすればこの問題を克服できますか?