Если у вас есть QGraphicsEllipseItem, который намного шире, чем высокий (сплющенный), он рисует вне своих границ. Это означает, что он не рисует правильно и оставляет на экране артефакты, когда вы перетаскиваете его. Это воспроизводит проблему (извинения не-питонисты, но это должно быть вполне понятно ERS C++):QGraphicsEllipseItem Краски за пределами границ, листья Артефакты
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 64bit, используя 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, но я подозреваю, что базовый класс просто говорит художнику рисовать эллипс, d придется много возиться, чтобы придумать мой собственный алгоритм рисования эллипса, который не использует малярный ...
Любые другие идеи? Что кажется наименее плохим вариантом? Я склоняюсь к тому, чтобы включить FullViewportUpdate.