에서 닫히지 클리핑하는 클립 어떻게 QGraphicsScene
와 QGraphicsView
가 나는 rect
의해 정의 scene
제한 지역 (행을 포함하거나, 베 지어 곡선 있음) 닫히지 경로를 그릴 필요가있다.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
에는 많은 선/베 지어가 포함될 수 있으므로 효과가 없으며 앤티 앨리어싱이 두 줄로 나쁘게 보입니다.
그래서 경로 생성 함수의 논리를 변경하지 않고 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를 :
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는())'트릭은 위대하다! –