2013-03-05 18 views
2

Если у вас есть 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.

ответ

3

Это проблема с QPen.

Если вы используете QPen с большей шириной (например, 1.2), проблема исчезает (если я правильно помню, по умолчанию для соединений, QPen расширяет строки, когда находит пересечение).