PyQt: переопределение QGraphicsView.drawItems - PullRequest
4 голосов
/ 17 июля 2009

Мне нужно настроить процесс рисования 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 вставлю код, который должен быть выполнен (глядя на gt-источники Qt), все работает. Хотя это не очень хорошее решение ... И я не понимаю, как оно могло вырваться из цикла?

Ответы [ 2 ]

3 голосов
/ 17 июля 2009

Есть исключение, которое возникает, когда предметы окрашены, но об этом сразу не сообщается. В моей системе (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 и не является виджетом, поэтому вполне вероятно, что это тоже неправильно.

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

1 голос
/ 17 июля 2009

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

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

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

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...