Перехват исключений MainLoop и отображение их в MessageDialogs

StackOverflow https://stackoverflow.com/questions/408810

Вопрос

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

Приведенный ниже код работает для кода инициализации в моем классе фрейма 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 больше нет метода с таким именем.

РЕДАКТИРОВАТЬ:

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

Решение sys.Exceptionhook слишком низкоуровневое и плохо работает с потоком основного цикла wxPython.Хотя ссылка на другой ответ делает то же самое, попробуйте/за исключением переноса вокруг основного цикла, который, опять же, не работает из-за того, что wxPython создает другой поток для приложения/UI.

Это было полезно?

Решение

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

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

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

  • Чендлер.py запускает приложение и устанавливает атрибут перенаправления, а также пытается перехватить и отобразить диалоговые окна ошибок в случае сбоя нормального запуска приложения.
  • Приложение.py настраивает объект приложения, включая настройку нашего индивидуального wx.PyOnDemandOutputWindow
  • обратная связь.py имеет реализацию настроенного wx.PyOnDemandOutputWindow;дополнительно потребуются файлы Feedback.xrc и Feedback_xrc.py.

Другие советы

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

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

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

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

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

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

Я считаю следующую статью очень полезной: вксПитон:Перехват исключений откуда угодно.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top