未封閉的路徑我有QGraphicsView
與QGraphicsScene
和我需要繪製未封閉的路徑(其可包含線或貝塞爾曲線)在由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_())
它吸引生成的路徑:
- 沒有削波。
- 隨着剪輯(路徑關閉,而不是隻是剪輯) - 這是我無法接受的。
- 最後,我想得到的結果(但是它是通過解決方法達成的)。
解決方法:關閉path
通過在reversed
的訂單中繪製它。但我的path
可能包含許多行/ beziers,所以它是無效的,並且抗鋸齒看起來不好用雙線。
所以問題是如何在不改變路徑生成函數的邏輯的情況下在QGraphicsScene中修剪未封閉的路徑或線?
UPDATE
現在,我使用下面的函數:
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)
更新2
更好的方法,@Hello W建議:
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())'伎倆是偉大的! – 2013-06-19 10:54:45