QGraphicsEllipseItem が高さよりもはるかに広い (平坦化されている) 場合、それは独自の境界の外に描画されます。これは、正しく描画されず、ドラッグすると画面にアーティファクトが残ることを意味します。これは問題を再現します (非 Pythonista には申し訳ありませんが、C++er には非常に理解できるはずです):
import sys
from PySide import QtCore, QtGui
if __name__ == '__main__':
app = QtGui.QApplication(sys.argv)
scene = QtGui.QGraphicsScene()
scene.setSceneRect(0, 0, 400, 400)
ellipse = QtGui.QGraphicsEllipseItem(QtCore.QRectF(0, 0, 320, 5))
ellipse.setFlag(QtGui.QGraphicsItem.ItemIsMovable, True)
ellipse.setFlag(QtGui.QGraphicsItem.ItemIsSelectable, True)
ellipse.setPos(40, 200)
ellipse.setPen(QtGui.QPen(QtCore.Qt.red, 1))
scene.addItem(ellipse)
view = QtGui.QGraphicsView(scene)
view.show()
sys.exit(app.exec_())
重要な点は、QGraphicsEllipseItem の幅が 320 で、高さがちょうど 5 であることです。楕円を選択すると、選択ボックスの破線が項目の境界に描画され、左右が異なることがわかります。楕円の端はそれらの境界の外にあります。次にアイテムをドラッグすると、アーティファクトが得られます。
問題があれば、これは PySide 1.1.2 を使用する Windows 7 64 ビット上にあります。
アンチエイリアスをオンにすると (例: view.setRenderHint(QtGui.QPainter.Antialiasing)
)、楕円はその境界内に描画され、すべて問題ありません。
エイリアスまたはアンチエイリアスでペイントするオプションがあればいいのですが、最後の手段として、より良い解決策がない限り、いつでもアンチエイリアスでペイントできます。私は QGraphicsEllipseItem をサブクラス化し、基本クラスの境界四角形の周りに大量のパディングを配置しました。
def boundingRect(self):
return QGraphicsEllipseItem.boundingRect(self).adjusted(-40, -40, 40, 40)
多くの場合、これで問題は解決しますが、楕円が非常に大きい場合、境界から遠く離れてしまう可能性があるため、追加するパディングの量を知るのは難しく、いずれにせよ、これはかなりくだらない解決策ですそれは、ほとんどの場合、私の境界が何マイルも離れていることを意味するためです(衝突検出などへの影響)。
ビューの更新モードを変更することでアーティファクトを停止することもできます。
view.setViewportUpdateMode(QtGui.QGraphicsView.FullViewportUpdate)
それが非常に平坦化されている場合に備えて、1つの GraphicsItem タイプの描画を処理するためにこれを行う必要があるのは少し悲しいようです...
私は自分の QGraphicsEllipseItem サブクラスで物事を「適切に」ペイントしようとすることができると思いますが、基本クラスはペインターに楕円を描くように指示しているだけなのではないかと思います。ペインターを使用しない独自の楕円描画アルゴリズム ...
他のアイデアはありますか?最も悪いオプションのように見えるものは何ですか? FullViewportUpdate をオンにするだけに傾いています。