私はQGraphicsView
をQGraphicsScene
としています。限定された範囲内の閉じられていないパス(線やベジエ曲線を含む場合があります)をrect
で定義する必要があります。Qt QGraphicsSceneで閉じていないパスをクリップする方法
をクリップする簡単な方法がありますがQPainterPath.intersected(path)
関数を使用してパスを閉じますが、path
は閉じていないであれば、その後、intersected
は(始点から端までの行を追加します)、それを閉じます。
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import functools
import sys
from PySide.QtCore import *
from PySide.QtGui import *
def path_through_points(points):
path = QPainterPath()
path.moveTo(*points[0])
for x, y in points[1:]:
path.lineTo(x, y)
return path
def path_through_points_workaround(points):
return path_through_points(points + list(reversed(points)))
if __name__ == "__main__":
app = QApplication(sys.argv)
scene = QGraphicsScene()
view = QGraphicsView(scene)
rect = QRectF(0, 0, 300, 300)
clip = QPainterPath()
clip.addRect(rect)
points = [(50, 50), (100, 100), (500, 300)]
def test_draw(path):
scene.clear()
scene.addRect(rect)
scene.addPath(path)
unclosed_path = path_through_points(points)
closed_path = path_through_points_workaround(points)
QTimer.singleShot(0, functools.partial(test_draw, unclosed_path))
QTimer.singleShot(2000, functools.partial(test_draw, unclosed_path.intersected(clip)))
QTimer.singleShot(4000, functools.partial(test_draw, closed_path.intersected(clip)))
view.resize(640, 480)
view.show()
sys.exit(app.exec_())
それが生成描くパス:クリッピングなし
-
は、ここに私の問題を説明する簡略化コードです。
- クリッピング(クリップの代わりにパスが閉じます) - これは私には受け入れられません。
- 最後に、私が得たい結果(しかし、回避策では到達しています)。
回避策:reversed
ためにそれを描くことによってpath
あります。しかし、私のpath
には多くの行/ベジエが含まれている可能性がありますので、効果的ではありません。アンチエイリアスは2行で悪く見えます。
QGraphicsSceneでパス生成関数のロジックを変更せずに、閉じられていないパスや行をクリップする方法はありますか?
UPDATE
今、私は次の関数使用しています:@Hello Wが提案されているよう
def clipped_path(path, min_x, min_y, max_x, max_y):
""" Returns clipped path, supports unclosed paths of any kind
(lines, beziers)
NOTE: Resulting path can loose antialiasing
"""
path.connectPath(path.toReversed())
clip = QPainterPath()
clip.addRect(QRectF(min_x, min_y, max_x, max_y))
return path.intersected(clip)
はUPDATE 2
より良い方法を:
class ClippedItemMixin(object):
def __init__(self, min_x, min_y, max_x, max_y):
self._clip_path = QtGui.QPainterPath()
self._clip_path.addRect(QtCore.QRectF(min_x, min_y, max_x, max_y))
super(ClippedItemMixin, self).__init__()
def paint(self, painter, *args, **kwargs):
painter.setClipPath(self._clip_path)
super(ClippedItemMixin, self).paint(painter, *args, **kwargs)
class ClippedPathItem(ClippedItemMixin, QtGui.QGraphicsPathItem):
pass
アンチエイリアシングが正しく機能するので、これでより見た目がよくなりました。
+1感謝を呼び出すことについて、 'path.connectPath(path.toReversedは())'トリックは素晴らしいです! –