Pyqt: переопределение qgraphicsview.drawitems
Вопрос
Мне нужно настроить процесс рисования QGraphicsView, и поэтому я переопределяю метод DrawItems, как это:
self.graphicsview.drawItems=self.drawer.drawItems
куда self.graphicsview
это qgraphicsview, и self.drawer
это пользовательский класс с методом drawItems
.
В этом методе я проверяю несколько флагов, чтобы решить, как нарисовать каждый элемент, а затем вызов item.paint
, как это:
def drawItems(self, painter, items, options):
for item in items:
print "Processing", item
# ... Do checking ...
item.paint(painter, options, self.target)
self.target
это QGraphicsView QGraphicsScene.
Однако, как только он достигнет item.paint
, он выходит из петли - без каких -либо ошибок. Если я поставлю условные условия вокруг картины и для каждого возможного типа QgraphicsItem вставьте код, который должен быть выполнен (глядя на QT Git-Fources), все работает.
Хотя не очень хорошее решение ... и я не понимаю, как это могло бы даже вырваться из петли?
Решение
Существует исключение, которое происходит, когда предметы окрашены, но об этом не сообщается сразу. В моей системе (PYQT 4.5.1, Python 2.6) не сообщается об исключении, когда я переплюсь по обезьяне. Следующий метод:
def drawItems(painter, items, options):
print len(items)
for idx, i in enumerate(items):
print idx, i
if idx > 5:
raise ValueError()
Выход:
45
0 <PyQt4.QtGui.QGraphicsPathItem object at 0x3585270>
1 <PyQt4.QtGui.QGraphicsSimpleTextItem object at 0x356ca68>
2 <PyQt4.QtGui.QGraphicsSimpleTextItem object at 0x356ce20>
3 <PyQt4.QtGui.QGraphicsSimpleTextItem object at 0x356cc88>
4 <PyQt4.QtGui.QGraphicsSimpleTextItem object at 0x356cc00>
5 <PyQt4.QtGui.QGraphicsSimpleTextItem object at 0x356caf0>
6 <PyQt4.QtGui.QGraphicsSimpleTextItem object at 0x356cb78>
Однако, как только я закрываю приложение, напечатан следующий метод:
Exception ValueError: ValueError() in <module 'threading' from '/usr/lib/python2.6/threading.pyc'> ignored
Я пытался печатать threading.currentThread()
, но он возвращает ту же нить, независимо от того, называется он в или вне обезьяны drawItems
метод
В вашем коде это, вероятно, связано с тем, что вы проходите options
(который является списком объектов параметров стиля) для отдельных элементов, а не соответствующего объекта опции. Использование этого кода должен дать вам правильные результаты:
def drawItems(self, painter, items, options):
for item, option in zip(items, options):
print "Processing", item
# ... Do checking ...
item.paint(painter, option, self.target)
Кроме того, вы говорите self.target
это объект сцены. А Документация для paint()
говорит:
Эта функция, которую обычно называют QGraphicsView, рисует содержимое предмета в локальных координатах. ... аргумент виджета является необязательным. Если предоставлено, он указывает на виджет, который нарисован; В противном случае, это 0. Для кэшированной живописи виджет всегда 0.
и тип QWidget*
. QGraphicsScene
наследует от QObject
и не является виджетом, поэтому вполне вероятно, что это тоже неправильно.
Тем не менее, тот факт, что исключение не сообщается вообще или не сразу, предполагает некоторую нечестную игру, вы должны связаться с сопровождающим.
Другие советы
Причина, по которой петля внезапно выходит, заключается в том, что исключение брошено. Python не справляется с этим (нет try:
Block), поэтому он передается в код CALL (QT C ++), который понятия не имеет об исключениях Python, поэтому он потерян.
Добавьте попытку/кроме петли, и вы должны увидеть причину, по которой это происходит.
Примечание. Поскольку Python 2.4, вы не должны больше переопределять методы таким образом.
Вместо этого вы должны получить новый класс из QgraphicsView и добавить свой drawItems()
Метод для этого нового класса. Это заменит исходный метод должным образом.
Не забудь позвонить super()
в __init__
Метод! В противном случае ваш объект не будет работать должным образом.