Pergunta

Eu tenho um aplicativo wxPython que depende de um arquivo de configuração externo.Quero fornecer caixas de diálogo de mensagens amigáveis ​​que apareçam se houver algum erro de configuração.Tentei fazer isso funcionar envolvendo minha chamada app.MainLoop() em uma instrução try/except.

O código abaixo funciona para o código init na minha classe de quadro MainWindow, mas não captura nenhuma exceção que ocorra no MainLoop.Como posso capturar essas exceções também?

if __name__ == '__main__':
    app = MyApp(0)
    try:
        MainWindow(None, -1, 'My Cool App')
        app.MainLoop()
    except ConfigParser.Error, error_message:
        messagebox = wx.MessageDialog(None, error_message, 'Configuration Error', wx.OK | wx.ICON_ERROR)
        messagebox.ShowModal()

Eu li algumas menções a um método OnExceptionInMainLoop que pode ser substituído na classe wx.App, mas a fonte que li deve estar desatualizada (2004), pois wx.App não parece mais ter um método com esse nome.

EDITAR:

Preciso ser capaz de capturar exceções não tratadas durante meu mainloop para poder tratá-las ainda mais e exibi-las em caixas de diálogo de erro, não passar silenciosamente e não encerrar o aplicativo.

A solução sys.excepthook é de nível muito baixo e não funciona bem com o thread principal wxPython.Enquanto o link para a outra resposta faz a mesma tentativa/exceto envolver o mainloop que não funciona devido, mais uma vez, ao wxPython gerar um thread diferente para o aplicativo/ui.

Foi útil?

Solução

Eu codifiquei algo assim para Chandler, onde qualquer exceção não tratada abre uma janela com a pilha e outras informações, e os usuários podem colocar comentários adicionais (o que eles fizeram quando isso aconteceu, etc.) e enviá-los para os desenvolvedores do Chandler.Um pouco como o Mozilla Talkback (hoje em dia eles usam o recurso Breakpad, eu acredito), se você preferir.

Para fazer isso no wxPython, você precisa fornecer o parâmetro de redirecionamento para wx.App.Isso irá aparecer wx.PyOnDemandOutputWindow (você provavelmente desejará substituí-lo para fornecer uma implementação mais bonita).

Os arquivos de origem relevantes no Chandler estão aqui:

  • Chandler.py inicia o aplicativo e define o atributo de redirecionamento, bem como tenta capturar e exibir caixas de diálogo de erro caso a inicialização normal do aplicativo falhe
  • Aplicativo.py personaliza o objeto do aplicativo, incluindo a configuração de nosso wx.PyOnDemandOutputWindow personalizado
  • feedback.py possui a implementação para o wx.PyOnDemandOutputWindow customizado;também precisará de feedback.xrc e feedback_xrc.py

Outras dicas

Não sei se isso funcionará para um aplicativo wxPython, mas no módulo sys você pode sobrescrever o atributo excepthook, que é uma função chamada com 3 argumentos, (type, value, traceback), quando uma exceção não detectada é capturada.Você pode instalar sua própria função que lida apenas com as exceções desejadas e chamar a função original para todas as outras.

Consultar: http://docs.python.org/library/sys.html#sys.excepthook

Talvez esse questão pode ser de alguma utilidade, ela tenta capturar todas as exceções.

Postando a solução que funcionou para mim com um problema muito semelhante.

import wx
import sys
import traceback

class Frame(wx.Frame):
    def __init__(self):
        wx.Frame.__init__(self, None)
        panel = wx.Panel(self)
        m_close = wx.Button(panel, -1, "Error")
        m_close.Bind(wx.EVT_BUTTON, self.OnErr)
    def OnErr(self, event):
        1/0

def handleGUIException(exc_type, exc_value, exc_traceback):
    err_msg = ''.join(traceback.format_exception(exc_type, exc_value, exc_traceback))
    err_msg += '\n Your App will now terminate'
    # Here collecting traceback and some log files to be sent for debugging.
    # But also possible to handle the error and continue working.
    dlg = wx.MessageDialog(None, err_msg, 'Termination dialog', wx.OK | wx.ICON_ERROR)
    dlg.ShowModal()
    dlg.Destroy()
    sys.exit()

sys.excepthook = handleGUIException

if __name__ == '__main__':
    app = wx.App(redirect=False) 
    top = Frame()
    top.Show()
    app.MainLoop()

Usando sys.excepthook está muito bem para mim.

Acho o seguinte artigo de grande ajuda: wxPython:Capturando exceções de qualquer lugar.

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