2009-07-17 4 views
4

Мне нужно настраивать процесс рисования в QGraphicsView, и так я переопределять метод drawItems так:PyQt: Переопределение 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 является QGraphicsScene в QGraphicsView в.
Однако, как только он достигает item.paint, он выходит из цикла - без каких-либо ошибок. Если я помещу условные обозначения вокруг картины, и для каждого возможного типа QGraphicsItem вставьте код, который должен быть выполнен (смотря на Qt git-sources), все работает.
Не очень хорошее решение, хотя ... И я не понимаю, как это может даже вырваться из цикла?

+0

Просто попробовал добавить этот оператор 'print item.paint', чтобы проверить, какой метод рисования будет вызываться. Он напечатал «<встроенную краску метода объекта QGraphicsPixmapItem в 0x02295588>». Встроенный? У меня также есть пользовательский объект, полученный из QGraphicsItem, и выше оператор дает «связанный метод ...». Что означает эта разница? – carlpett

+0

«встроенный» означает, что скомпилированный код в библиотеке Qt вызывается, а «связанный метод» означает, что вызывается код Python. –

ответ

3

Существует исключение, которое происходит, когда элементы окрашиваются, но об этом не сообщается сразу. В моей системе (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 является объектом сцены.documentation for paint() говорит:

Эта функция, которая обычно вызывается QGraphicsView, рисует содержимое элемента в локальных координатах. ... Аргумент виджета не является обязательным. Если он предоставлен, он указывает на виджет, который нарисован; в противном случае это 0. Для кешированной живописи виджет всегда равен 0.

и тип QWidget*. QGraphicsScene наследует от QObject и не является виджетами, поэтому вполне вероятно, что это тоже неправильно.

Тем не менее, факт, что исключение не сообщается вообще или не сразу, предполагает какую-то нечестную игру, вы должны связаться с сопровождающим.

+0

Hm. Я не получаю эту ошибку. Тем не менее, я получаю «аргумент 2 QGraphicsPolygonItem.paint() имеет недопустимый тип». Аргумент 2 - параметр-параметр, который передается без изменений. Выполнение 'type (options)' говорит мне, что это стандартный список Python, поэтому он сбрасывается, но не может быть повторно поднят. Это должно быть ошибка в упаковщиках? – carlpett

+0

Просто перечитайте документы и немного поиграйте и поняли одно и то же (список опций). Спасибо за вашу помощь! Это странно, что исключение не похоже на поверхность, если я не окружаю его попыткой/кроме ... – carlpett

1

Причина, по которой цикл внезапно завершается, заключается в том, что выбрано исключение. Python не обрабатывает его (блока try:), поэтому он передается вызываемому (Qt-код C++), который понятия не имеет о исключениях Python, поэтому он потерян.

Добавьте попытку/исключение вокруг цикла, и вы увидите причину, по которой это происходит.

Примечание: с Python 2.4 вы больше не должны переопределять методы таким образом.

Вместо этого вы должны получить новый класс из QGraphicsView и добавить свой метод drawItems() в этот новый класс. Это правильно заменит исходный метод.

Не забудьте позвонить по телефону super() в метод __init__! В противном случае ваш объект будет работать неправильно.

+0

Но ... Мой метод переопределения называется правильно? – carlpett

+0

Это скорее случайность, чем намерение. –

+0

Нет, главное, что работает, я только что проверил его. –