QGraphicsEllipseItem绘制外部边界,留下文物

时间:2013-03-05 13:15:27

标签: python qt pyqt pyside

如果你有一个QGraphicsEllipseItem比它更宽(扁平化),它会超出自己的界限。这意味着它不能正确绘制,并在您拖动它时在屏幕上留下瑕疵。这再现了这个问题(向非Pythonistas道歉,但它对C ++ ers来说应该是可以理解的):

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。如果选择椭圆,选择框的虚线将绘制在项目的边界,您可以看到椭圆的左右边缘位于这些边界之外。如果你然后拖动项目,你会得到文物。

这是在Windows 7 64位上使用PySide 1.1.2,如果重要的话。

如果启用消除锯齿功能(例如view.setRenderHint(QtGui.QPainter.Antialiasing)),椭圆会在其边界内绘制,一切都很好。

我宁愿选择绘画别名或反锯齿,但作为最后的手段,除了任何人都有更好的解决方案之外,我总是可以画出反锯齿。我已经将QGraphicsEllipseItem子类化,并在基类的边界矩阵周围放置了大量填充,如:

def boundingRect(self):
    return QGraphicsEllipseItem.boundingRect(self).adjusted(-40, -40, 40, 40)

这解决了很多情况下的问题,但是如果椭圆非常大,你可以在边界之外走很长的路,所以很难知道要添加多少填充,无论如何这是一个相当糟糕的解决方案,因为它意味着我的界限在大多数情况下都是英里数(对碰撞检测的影响等)。

您还可以通过更改视图上的更新模式来停止工件,即:

view.setViewportUpdateMode(QtGui.QGraphicsView.FullViewportUpdate)

这似乎有点伤心,不得不这样做只是因为它是非常扁平化的情况下,处理一个GraphicsItem类型的画...

我想我可以尝试在我自己的QGraphicsEllipseItem子类中'正确'绘制这个东西,但我怀疑基类只是告诉画家绘制一个椭圆,所以我不得不乱搞很多东西来用我自己的椭圆绘制算法,不使用画家...

还有其他想法吗?什么似乎是最不好的选择?我倾向于只打开FullViewportUpdate。

1 个答案:

答案 0 :(得分:3)

这是QPen的一个问题。

如果你使用宽度更大的QPen(例如1.2),问题就会消失(如果我没记错的话,默认情况下,对于连接,QPen会在找到交叉点时扩展线条。)