Перехват исключений MainLoop и отображение их в MessageDialogs - PullRequest
2 голосов
/ 03 января 2009

У меня есть приложение wxPython, которое использует внешний файл конфигурации. Я хочу предоставить дружественные диалоги сообщений, которые появляются, если есть какие-либо ошибки конфигурации. Я попытался сделать это, поместив мой вызов app.MainLoop () в оператор try / исключением.

Приведенный ниже код работает для кода инициализации в моем классе фрейма MainWindow, но не перехватывает никаких исключений, возникающих в MainLoop. Как я могу поймать и эти исключения?

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()

Я читал некоторые упоминания о методе OnExceptionInMainLoop, который можно переопределить в классе wx.App, но источник, который я читаю, должен быть устаревшим (2004), так как wx.App, похоже, больше не имеет метода, имя.

EDIT:

Мне нужно иметь возможность перехватывать необработанные исключения во время основного цикла, чтобы я мог дополнительно обрабатывать их и отображать их в диалоговых окнах ошибок, не передавать молча и не завершать работу приложения.

Решение sys.excepthook слишком низкого уровня и не очень хорошо работает с потоком mainloop wxPython. В то время как ссылка на другой ответ делает ту же самую попытку / за исключением обтекания основного цикла, который не работает, еще раз, из-за того, что wxPython порождает другой поток для app / ui.

Ответы [ 5 ]

2 голосов
/ 03 января 2009

Не знаю, будет ли это работать для приложения wxPython, но в модуле sys вы можете перезаписать атрибут exchook, который является функцией с 3 аргументами, (type, value, traceback), когда перехватывается исключение uncaugth. Вы можете установить там свою собственную функцию, которая обрабатывает только те исключения, которые вы хотите, и вызывать оригинальную функцию для всех остальных.

Консультируйтесь: http://docs.python.org/library/sys.html#sys.excepthook

1 голос
/ 05 февраля 2009

Я написал нечто подобное для Chandler , где любые необработанные исключения всплывают в окне со стеком и другой информацией, и пользователи могут добавлять дополнительные комментарии (что они делали, когда это происходило и т. Д.) и представить его разработчикам Чендлера. Немного похоже на Mozilla Talkback ( в настоящее время они используют Breakpad, я полагаю), если хотите.

Чтобы сделать это в wxPython, вам нужно предоставить параметр перенаправления в wx.App. Это выскочит wx.PyOnDemandOutputWindow (вы, вероятно, захотите переопределить его, чтобы обеспечить более привлекательную реализацию).

Соответствующие исходные файлы в Chandler находятся здесь:

  • Chandler.py запускает приложение и устанавливает атрибут перенаправления, а также пытается перехватить и отобразить диалоги ошибок в случае сбоя при нормальном запуске приложения
  • Application.py настраивает объект приложения, включая настройку нашего настроенного wx.PyOnDemandOutputWindow
  • feedback.py имеет реализацию для настроенного wx.PyOnDemandOutputWindow; ему также понадобятся feedback.xrc и feedback_xrc.py
0 голосов
/ 25 октября 2018

Использование sys.excepthook очень хорошо для меня.

Мне очень полезна следующая статья: wxPython: отлов исключений из любого места .

0 голосов
/ 24 августа 2012

Публикация решения, которое работало для меня с очень похожей проблемой.

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()
0 голосов
/ 03 января 2009

Возможно этот вопрос может быть полезен, он пытается охватить все исключения.

...