这条简单的线路:
wx.MessageBox('Foo', 'Bar', wx.OK | wx.ICON_ERROR)
给我一个错误图标和Windows错误噪声的消息框(这是不一样的噪音wx.Bell()
)。 我想为未捕获的exception创build一个自定义错误对话框,其中回溯在文本控件中可用,我想包括Windows错误图标和噪声。 我知道两个版本的Windows都不一样,甚至可以自定义错误噪音。
有没有任何直接的方式与wxPython使用这些本地Windows资源? 红利问题; 如果答案是否定的,那么做什么是最直接的做法呢?
我只是想在匿名懦夫的出色答案之后炫耀结果,因为他们远远超出了我的预期。 这是现在popup的未处理的exception(在Windows 8上)的错误对话框:
它还包含现代Windows“UNNK!” 错误的声音。 这是对话框背后的代码。 我把它放在一个单独的模块,当它被导入时覆盖sys.excepthook
:
"""This module, when imported, overrides the default unhandled exception hook with one that displays a fancy wxPython error dialog.""" import sys import textwrap import traceback import winsound import wx def custom_excepthook(exception_type, value, tb): dialog = ExceptionDialog(exception_type, value, tb) dialog.ShowModal() # Override sys.excepthook sys.excepthook = custom_excepthook class ExceptionDialog(wx.Dialog): """This class displays an error dialog with details information about the input exception, including a traceback.""" def __init__(self, exception_type, exception, tb): wx.Dialog.__init__(self, None, -1, title="Unhandled error", style=wx.DEFAULT_DIALOG_STYLE | wx.RESIZE_BORDER) self.SetSize((640, 480)) self.SetMinSize((420, 200)) self.exception = (exception_type, exception, tb) self.initialize_ui() winsound.MessageBeep(winsound.MB_ICONHAND) def initialize_ui(self): extype, exception, tb = self.exception panel = wx.Panel(self, -1) # Create the top row, containing the error icon and text message. top_row_sizer = wx.BoxSizer(wx.HORIZONTAL) error_bitmap = wx.ArtProvider.GetBitmap( wx.ART_ERROR, wx.ART_MESSAGE_BOX ) error_bitmap_ctrl = wx.StaticBitmap(panel, -1) error_bitmap_ctrl.SetBitmap(error_bitmap) message_text = textwrap.dedent("""\ I'm afraid there has been an unhandled error. Please send the contents of the text control below to the application's developer.\ """) message_label = wx.StaticText(panel, -1, message_text) top_row_sizer.Add(error_bitmap_ctrl, flag=wx.ALL, border=10) top_row_sizer.Add(message_label, flag=wx.ALIGN_CENTER_VERTICAL) # Create the text control with the error information. exception_info_text = textwrap.dedent("""\ Exception type: {} Exception: {} Traceback: {}\ """) exception_info_text = exception_info_text.format( extype, exception, ''.join(traceback.format_tb(tb)) ) text_ctrl = wx.TextCtrl(panel, -1, style=wx.TE_MULTILINE | wx.TE_DONTWRAP) text_ctrl.SetValue(exception_info_text) # Create the OK button in the bottom row. ok_button = wx.Button(panel, -1, 'OK') self.Bind(wx.EVT_BUTTON, self.on_ok, source=ok_button) ok_button.SetFocus() ok_button.SetDefault() sizer = wx.BoxSizer(wx.VERTICAL) sizer.Add(top_row_sizer) # sizer.Add(message_label, flag=wx.ALL | wx.EXPAND, border=10) sizer.Add(text_ctrl, proportion=1, flag=wx.EXPAND) sizer.Add(ok_button, flag=wx.ALIGN_CENTER | wx.ALL, border=5) panel.SetSizer(sizer) def on_ok(self, event): self.Destroy()
我所希望的唯一的改进是静态文本根据对话框的宽度自动stream动和包装,但是我不能为此而自定义控件类。
wx.MessageBox
调用特定于操作系统的标准消息/提醒对话框(在windows上,这是来自user32.dll的MessageBox() )。 wxWidgets只是将你提供的标志(如wx.OK和wx.ICON_INFORMATION)转换为本地消息框的os特定标志和选项。
您可以通过wx.ArtProvider
获取特定于操作系统的图标。
至于声音, wx.Sound
只能播放声音文件。 但是,如果应用程序不必是可移植的,则可以使用winsound
模块。
import wx import winsound # windows only class Frame(wx.Frame): def __init__(self): wx.Frame.__init__(self,None,wx.ID_ANY) sizer = wx.BoxSizer(wx.HORIZONTAL) sizer.Add( wx.StaticBitmap(self,bitmap=wx.ArtProvider.GetBitmap(wx.ART_INFORMATION)) ) sizer.Add( wx.StaticBitmap(self,bitmap=wx.ArtProvider.GetBitmap(wx.ART_QUESTION)) ) sizer.Add( wx.StaticBitmap(self,bitmap=wx.ArtProvider.GetBitmap(wx.ART_WARNING)) ) sizer.Add( wx.StaticBitmap(self,bitmap=wx.ArtProvider.GetBitmap(wx.ART_ERROR)) ) self.SetSizerAndFit(sizer) self.Show() winsound.MessageBeep(winsound.MB_ICONASTERISK) winsound.PlaySound('SystemHand', winsound.SND_ASYNC | winsound.SND_ALIAS) app = wx.PySimpleApp() Frame() app.MainLoop()