Pergunta

Preciso personalizar o processo de desenho de um QGraphicsView e, portanto, substituo o método DrawItems como este:

self.graphicsview.drawItems=self.drawer.drawItems

Onde self.graphicsview é um QGraphicsView, e self.drawer é uma aula personalizada com um método drawItems.
Neste método, verifico algumas bandeiras para decidir como desenhar cada item e depois ligar item.paint, assim:

def drawItems(self, painter, items, options):
    for item in items:
        print "Processing", item
        # ... Do checking ...
        item.paint(painter, options, self.target)

self.target é a qGraphicsScene do QGraphicsView.
No entanto, uma vez que chega item.paint, ele sai do loop - sem erros. Se eu colocar condicionais em torno da pintura, e para cada tipo possível de qgraphicsitem colar o código que deveria ser executado (olhando para as fontes QT Git), tudo funciona.
Não é uma solução muito boa ... e eu não entendo como isso poderia sair do loop?

Foi útil?

Solução

Há uma exceção que ocorre quando os itens são pintados, mas não são relatados imediatamente. No meu sistema (PYQT 4.5.1, Python 2.6), nenhuma exceção é relatada quando eu fico com macaco o seguinte método:

def drawItems(painter, items, options):
    print len(items)
    for idx, i in enumerate(items):
        print idx, i
        if idx > 5:
            raise ValueError()

Resultado:

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>

No entanto, depois de fechar o aplicativo, o seguinte método é impresso:

Exception ValueError: ValueError() in <module 'threading' from '/usr/lib/python2.6/threading.pyc'> ignored

Eu tentei imprimir threading.currentThread(), mas retorna o mesmo fio, seja chamado dentro ou fora do macaco drawItems método.

No seu código, isso provavelmente se deve ao fato de você passar options (que é uma lista de objetos de opções de estilo) para os itens individuais, em vez do objeto de opção respectivo. O uso deste código deve fornecer os resultados corretos:

def drawItems(self, painter, items, options):
    for item, option in zip(items, options):
        print "Processing", item
        # ... Do checking ...
        item.paint(painter, option, self.target)

Além disso, você diz o self.target é o objeto de cena. o documentação para paint() diz:

Essa função, que geralmente é chamada pelo QGraphicsView, pinta o conteúdo de um item nas coordenadas locais. ... O argumento do widget é opcional. Se fornecido, aponta para o widget que está sendo pintado; Caso contrário, é 0. Para pintura em cache, o widget é sempre 0.

e o tipo é QWidget*. QGraphicsScene herda de QObject e não é um widget, por isso é provável que isso também esteja errado.

Ainda assim, o fato de a exceção não ser relatada ou não imediatamente sugere algum jogo sujo, você deve entrar em contato com o mantenedor.

Outras dicas

A razão pela qual o loop sai repentinamente é que uma exceção é lançada. Python não lida com isso (não há try: bloco), por isso é passado para o chamado (código C ++ da QT), que não tem idéia das exceções do Python, por isso está perdido.

Adicione uma tentativa/exceto ao redor do loop e você verá o motivo pelo qual isso acontece.

Nota: Como o Python 2.4, você não deve mais substituir os métodos dessa maneira.

Em vez drawItems() Método para esta nova classe. Isso substituirá o método original corretamente.

Não se esqueça de ligar super() no __init__ método! Caso contrário, seu objeto não funcionará corretamente.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top