PySide aguarda o sinal do thread principal em um thread de trabalho

Decidi adicionar uma GUI a um dos meus scripts. O script é um simples raspador da web. Decidi usar um segmento de trabalho, pois o download e a análise dos dados podem demorar um pouco. Decidi usar o PySide, mas meu conhecimento do Qt em geral é bastante limitado.

Como o script deve aguardar a entrada do usuário ao encontrar um captcha, eu decidi que ele deveria esperar até que umQLineEdit incêndiosreturnPressed e, em seguida, envie o conteúdo para o segmento de trabalho, para que ele possa ser enviado para validação. Isso deve ser melhor do que esperar muito tempo para pressionar a tecla de retorn

Parece que esperar por um sinal não é tão direto quanto eu pensava que seria e, depois de pesquisar por um tempo, encontrei várias soluções semelhantes aest. A sinalização através de threads e um loop de evento local no thread de trabalho tornam minha solução um pouco mais complicad

epois de mexer nele por várias horas, ele ainda não funcionar

O que deveria acontecer:

Faça o download dos dados até fazer referência ao captcha e insira um loop Faça o download do captcha e exiba-o para o usuário, inicieQEventLoop chamandoself.loop.exec_()SaídaQEventLoop chamandoloop.quit() em um slot de threads de trabalho conectado viaself.line_edit.returnPressed.connect(self.worker.stop_waiting) nomain_window class Valide o captcha e faça o loop se a validação falhar; caso contrário, tente novamente o último URL que deve estar disponível para download agora e prossiga com o próximo URL

O que acontece

...Veja acima..

ExitingQEventLoop não funciona.self.loop.isRunning() retornaFalse depois de chamar seuexit(). self.isRunning retornaTrue, como tal, o fio não parecia morrer em circunstâncias estranhas. Ainda assim, o fio pára noself.loop.exec_() linha. Como tal, o encadeamento está travado executando o loop de eventos, mesmo que o loop de eventos me diga que não está mais em execuçã

A GUI responde da mesma forma que os slots da classe de encadeamento de trabalho. Consigo ver o texto sendo enviado para o segmento de trabalho, o status do loop de eventos e o próprio segmento, mas nada após a execução da linha acima mencionad

O código é um pouco complicado, portanto adiciono um pouco de pseudo-código-python-mix, deixando de fora as sem importância:

class MainWindow(...):
    # couldn't find a way to send the text with the returnPressed signal, so I
    # added a helper signal, seems to work though. Doesn't work in the
    # constructor, might be a PySide bug?
    helper_signal = PySide.QtCore.Signal(str)
    def __init__(self):
        # ...setup...
        self.worker = WorkerThread()
        self.line_edit.returnPressed.connect(self.helper_slot)
        self.helper_signal.connect(self.worker.stop_waiting)

    @PySide.QtCore.Slot()
    def helper_slot(self):
        self.helper_signal.emit(self.line_edit.text())

class WorkerThread(PySide.QtCore.QThread):
    wait_for_input = PySide.QtCore.QEventLoop()

    def run(self):
        # ...download stuff...
        for url in list_of_stuff:
            self.results.append(get(url))

    @PySide.QtCore.Slot(str)
    def stop_waiting(self, text):
        self.solution = text
        # this definitely gets executed upon pressing return
        self.wait_for_input.exit()

    # a wrapper for requests.get to handle captcha
    def get(self, *args, **kwargs):
        result = requests.get(*args, **kwargs)
        while result.history: # redirect means captcha
            # ...parse and extract captcha...
            # ...display captcha to user via not shown signals to main thread...

            # wait until stop_waiting stops this event loop and as such the user
            # has entered something as a solution
            self.wait_for_input.exec_()

            # ...this part never get's executed, unless I remove the event
            # loop...

            post = { # ...whatever data necessary plus solution... }
            # send the solution
            result = requests.post('http://foo.foo/captcha_url'), data=post)
        # no captcha was there, return result
        return result

frame = MainWindow()
frame.show()
frame.worker.start()
app.exec_()