Issue
I have a QPainterPath composed of a few curves.
import sys
from PyQt5.QtWidgets import *
from PyQt5.QtCore import *
from PyQt5.QtGui import *
if __name__ == '__main__':
app = QApplication(sys.argv)
path = QPainterPath(QPoint(80, 70))
path.quadTo(-50, 128, 90, 113)
path.lineTo(193, 83)
path.cubicTo(275, 43, 292, 5, 176, 41)
path.moveTo(82, 80)
path.cubicTo(75, 18, 160, 6, 179, 48)
pix = QPixmap(280, 150)
pix.fill(Qt.transparent)
qp = QPainter(pix)
qp.setRenderHint(QPainter.Antialiasing)
qp.setPen(QPen(Qt.black, 4, Qt.SolidLine, Qt.RoundCap, Qt.RoundJoin))
qp.setBrush(Qt.green)
qp.drawPath(path)
label = QLabel(pixmap=pix, visible=True)
sys.exit(app.exec_())
I'm trying to get the unfilled area to be considered as being inside the path's outline (so it gets filled as well). Separating the last curve into another QPainterPath and uniting them fills the area but removes part of the outline that extends downwards.
path = QPainterPath(QPoint(80, 70))
path.quadTo(-50, 128, 90, 113)
path.lineTo(193, 83)
path.cubicTo(275, 43, 292, 5, 176, 41)
path2 = QPainterPath()
path2.moveTo(82, 80)
path2.cubicTo(75, 18, 160, 6, 179, 48)
...
qp.drawPath(path.united(path2))
path.intersected(path2)
will return a QPainterPath of the unfilled region but with an outline around it. Adding path2
and the intersection to path
will fill the whole area but it now has the extra outlines.
intersection = path.intersected(path2)
path.addPath(path2)
path.addPath(intersection)
...
qp.drawPath(path)
And that's as close as I've come. To be clear, this is what I want to get as one QPainterPath object:
I know I can fill the intersection separately on the paint device with QPainter.fillPath
(as done for this image), but that's not what I want. I need a single QPainterPath which includes that unfilled region as being part of path. (Painting it on a pixmap is just to verify if it behaves as desired). I'm sure it must be possible, I'm not sure what combination of QPainterPath methods to use to obtain it.
Solution
The reason of this is that you're moving to the opposite side of the curve, which practically creates a new superimposed path that is considered outside of the previous. In this case, even using setFillRule()
to QtCore.Qt.WindingFill
will not give you the appropriate result.
The solution is to invert the curve, and move to the closest position of the previous path:
path = QPainterPath(QPoint(80, 70))
path.quadTo(-50, 128, 90, 113)
path.lineTo(193, 83)
path.cubicTo(275, 43, 292, 5, 176, 41)
path.moveTo(179, 48)
path.cubicTo(160, 6, 75, 18, 82, 80)
Answered By - musicamante
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.