Obtendo erros erráticos de “assinatura de sinal inválida” no PySide QWebPage
Pergunta
Estou criando um aplicativo que automatiza o carregamento de páginas da web e a criação de capturas de tela (não, não posso usar uma das soluções existentes) usando PySide. Uma parte do aplicativo obtém uma lista de URLs e carrega cada URL por vez, usando um objeto novo QWebPage. Depois que a página é carregada, uma captura de tela é tirada e o objeto QWebPage é excluído.
De vez em quando, com execuções suficientes, recebo o seguinte erro de PySide, como uma exceção RuntimeError:
Invalid Signal signature: loadStarted()
Failed to connect signal loadStarted().
A primeira linha é impressa em STDERR (provavelmente pelo Qt?) e a segunda linha é a exceção Python.
loadStarted () é um sinal QWebPage embutido, não algo que eu criei. Isso funciona 90% do tempo, e eu não conseguia descobrir o que o fazia falhar ocasionalmente.
Para ser honesto, este aplicativo tem um design bastante incomum, pois conecta PySide / Qt em um aplicativo da web servido por uWSGI - isso significa que, por exemplo, não estou usando o loop de evento QApplication, mas sim um loop de evento local para cada página carregar. Também não tenho experiência em Qt ou Python, então é possível que eu esteja cometendo muitos erros, mas não consigo descobrir quais são.
Estou pensando que esta postagem pode ter algo a ver com isso, mas estou não tenho certeza.
Alguma sugestão sobre onde procurar a seguir?
ATUALIZAÇÃO: o sinal está conectado através do seguinte código:
class MyWebPage(QWebPage):
def __init__(self, parent=None):
super(MyWebPage, self).__init__(parent)
self.loadStarted.connect(self.started)
self.loadFinished[bool].connect(self.finished)
Os objetos MyWebPage são criados como filhos de uma única instância única de QObject diferente, que não é excluída até que o processo seja encerrado. Eles são excluídos chamando page.deleteLater () assim que eu terminar de usá-los. Como estou executando um loop de evento local, eu aciono exclusões adiadas para acontecer após sair do loop de evento local chamando:
# self.eventLoop is the local event loop, which at this stage is not running
self.eventLoop.processEvents()
# self.app is the QApplication instance
self.app.sendPostedEvents(None, QEvent.DeferredDelete)
Solução 2
Para o que vale a pena, este e outras questões foram finalmente resolvidos de forma decente depois que eu atualizei para Pyside 1.2.1.
Outras dicas
Eu estava tendo o mesmo problema (recebia esses erros de vez em quando, mas não conseguia reproduzi-los de forma consistente). Acho que você pode estar certo de que tem algo a ver com métodos não existentes quando você tenta conectar os sinais a eles - apenas para testar isso, coloquei as chamadas .connect em um método separado e os erros foram embora . Por exemplo:
EDITAR: (algumas horas depois) Acho que falei cedo demais - acabei de receber o erro de novo.
ATUALIZAÇÃO: (algumas semanas depois)
Eu brinquei muito com a sintaxe e ocasionalmente até obtive um RuntimeError (possivelmente este bug em PySide?). Ainda não tenho certeza do porquê, mas como o erro ocorre de maneira inconsistente, você provavelmente está seguro em forçá-lo desta forma:
class MyWebPage(QWebPage):
def __init__(self, parent=None):
super(MyWebPage, self).__init__(parent)
success = False
while not success:
try:
success = self.loadStarted.connect(self.started)
except RuntimeError:
success = False
success = False
while not success:
try:
success = self.loadFinished[bool].connect(self.finished)
except RuntimeError:
success = False
Se você realmente quiser estar seguro, talvez possa manter um contador de loop e apenas travar o programa se o sinal não conectar corretamente antes de algum limite.