WXPython错误处理和重复使用

发布于 2024-10-14 20:18:16 字数 4956 浏览 5 评论 0原文

我有一个 wx python 应用程序,当您单击按钮时,它会针对特定输入执行一系列步骤。该应用程序第一次运行,但如果我尝试使用不同的输入值第二次单击该按钮,它会抛出错误。

我有两个问题: 1.) 如何修复下面的代码以使其停止抛出此错误消息?

2.) 我应该添加什么特定代码,以便在对话框中向最终用户显示任何此类错误消息?我希望它能够优雅地终止引发错误的整个过程(从单击按钮开始),并将进度条替换为一个新的对话框,该对话框给出错误消息并允许用户单击一个按钮他们返回到应用程序的主窗口,以便他们可以尝试再次单击该按钮以使其能够处理新的输入。我很快就会将其封装在一个 exe 文件中,但现在唯一的错误处理是 python shell 中的错误消息。由于用户没有 python shell,因此我需要以本段中描述的方式显示错误消息。请注意,我的 OnClick() 函数在这里实例化了一个类。我在实际代码中使用了许多不同的类,每个类都非常复杂,并且我需要我在这里要求的功能,以便能够处理正在发生的各个类内部深处发生的错误。由 OnClick() 函数实例化。

这是我的代码的一个非常简化但有效的版本:

import wxversion
import wx
ID_EXIT = 130

class MainWindow(wx.Frame):
    def __init__(self, parent,id,title):
        wx.Frame.__init__(self,parent,wx.ID_ANY,title, size = (500,500), style = wx.DEFAULT_FRAME_STYLE | wx.NO_FULL_REPAINT_ON_RESIZE)

        # A button
        self.button =wx.Button(self, label="Click Here", pos=(160, 120))
        self.Bind(wx.EVT_BUTTON,self.OnClick,self.button)

        # the combobox Control
        self.sampleList = ['first','second','third']
        self.lblhear = wx.StaticText(self, label="Choose TestID to filter:", pos=(20, 75))
        self.edithear = wx.ComboBox(self, pos=(160, 75), size=(95, -1), choices=self.sampleList, style=wx.CB_DROPDOWN)

        # the progress bar
        self.progressMax = 3
        self.count = 0
        self.newStep='step '+str(self.count)
        self.dialog = None

        #-------Setting up the menu.
        # create a new instance of the wx.Menu() object
        filemenu = wx.Menu()

        # enables user to exit the program gracefully
        filemenu.Append(ID_EXIT, "E&xit", "Terminate the program")

        #------- Creating the menu.
        # create a new instance of the wx.MenuBar() object
        menubar = wx.MenuBar()
        # add our filemenu as the first thing on this menu bar
        menubar.Append(filemenu,"&File")
        # set the menubar we just created as the MenuBar for this frame
        self.SetMenuBar(menubar)
        #----- Setting menu event handler
        wx.EVT_MENU(self,ID_EXIT,self.OnExit)

        self.Show(True)

    def OnExit(self,event):
        self.Close(True)

    def OnClick(self,event):
        #SECOND EDIT: added try: statement to the next line:
        try:
            if not self.dialog:
                self.dialog = wx.ProgressDialog("Progress in processing your data.", self.newStep,
                                            self.progressMax,
                                            style=wx.PD_CAN_ABORT
                                            | wx.PD_APP_MODAL
                                            | wx.PD_SMOOTH)
            self.count += 1
            self.newStep='Start'
            (keepGoing, skip) = self.dialog.Update(self.count,self.newStep)
            TestID = self.edithear.GetValue()

            self.count += 1
            self.newStep='Continue.'
            (keepGoing, skip) = self.dialog.Update(self.count,self.newStep)
            myObject=myClass(TestID)
            print myObject.description

            self.count += 1
            self.newStep='Finished.'
            (keepGoing, skip) = self.dialog.Update(self.count,self.newStep)

            **#FIRST EDIT: Added self.count = 0 on the following line**
            self.count = 0

            self.dialog.Destroy()

        #SECOND EDIT: Added the next seven lines to handle exceptions.
        except:
            self.dialog.Destroy()
            import sys, traceback
            xc = traceback.format_exception(*sys.exc_info())
            d = wx.MessageDialog( self, ''.join(xc),"Error",wx.OK)
            d.ShowModal() # Show it
            d.Destroy() #finally destroy it when finished


    class myClass():
        def __init__(self,TestID):
            self.description = 'The variable name is:  '+str(TestID)+'. '

app = wx.PySimpleApp()
frame = MainWindow(None,-1,"My GUI")
app.MainLoop()

我的实际代码要复杂得多,但我创建了它的这个虚拟版本来说明它的问题。当我第一次单击按钮时在 python 中运行上面的代码时,它会起作用。但是,如果我尝试第二次单击该按钮,我会在 python shell 中收到以下错误消息:

Traceback (most recent call last):
  File "mypath/GUIdiagnostics.py", line 55, in OnClick
    (keepGoing, skip) = self.dialog.Update(self.count,self.newStep)
  File "C:\Python26\lib\site-packages\wx-2.8-msw-unicode\wx\_windows.py", line 2971, in Update
    return _windows_.ProgressDialog_Update(*args, **kwargs)
wx._core.PyAssertionError: C++ assertion "value <= m_maximum" failed at ..\..\src\generic\progdlgg.cpp(337) in wxProgressDialog::Update(): invalid progress value

内容来回答上面的第一个问题

self.count = 0

添加以上

self.dialog.Destroy()

第一次编辑: 好的,我通过在上面的代码中 。但是我的第二个问题关于上面代码中的错误处理呢?有人能帮我吗?当然,wxpython 中的错误处理是一个常见问题,有已知的方法可以解决。我将使用 py2exe 将此应用程序打包到一个 exe 文件中。


第二次编辑:我用我已添加到上面代码中的 try: , except: 语句回答了上面的第二个问题。有趣的是,这是第一次在堆栈溢出上没有人能够回答我的问题。我对这种类型的编程很陌生,所以很多东西我都是随手拿起的。这个问题现在有了答案。

I have a wx python application that performs a series of steps for a particular input when you click on a button. The application works the first time, but then it throws an error if I try to click on the button a second time with a different input value.

I have two questions:
1.) How do I fix my code below so that it stops throwing this error message?

2.) What specific code should I add so that any error message such as this one is shown to the end user in a dialog box? I would like it to be able to gracefully kill the whole process that threw the error (starting with the button click) and replace the progress bar with a new dialog box that gives the error message and allows the user to click a button that will take them back to the application's main window so that they can try to click the button again to make it work with new input. I am about to wrap this up in an exe file soon, but right now the only error handling I have is the error message in the python shell. Since users will not have the python shell, I need the error messages to come up in the manner described in this paragraph. Notice that my OnClick() function here instantiates a class. I make use of a number of different classes in my actual code, each of which is very complex, and I need the functionality I am asking for here to be able to handle errors that happen deep in the bowels of the various classes that are being instantiated by the OnClick() function.

Here is a very simplified but working version of my code:

import wxversion
import wx
ID_EXIT = 130

class MainWindow(wx.Frame):
    def __init__(self, parent,id,title):
        wx.Frame.__init__(self,parent,wx.ID_ANY,title, size = (500,500), style = wx.DEFAULT_FRAME_STYLE | wx.NO_FULL_REPAINT_ON_RESIZE)

        # A button
        self.button =wx.Button(self, label="Click Here", pos=(160, 120))
        self.Bind(wx.EVT_BUTTON,self.OnClick,self.button)

        # the combobox Control
        self.sampleList = ['first','second','third']
        self.lblhear = wx.StaticText(self, label="Choose TestID to filter:", pos=(20, 75))
        self.edithear = wx.ComboBox(self, pos=(160, 75), size=(95, -1), choices=self.sampleList, style=wx.CB_DROPDOWN)

        # the progress bar
        self.progressMax = 3
        self.count = 0
        self.newStep='step '+str(self.count)
        self.dialog = None

        #-------Setting up the menu.
        # create a new instance of the wx.Menu() object
        filemenu = wx.Menu()

        # enables user to exit the program gracefully
        filemenu.Append(ID_EXIT, "E&xit", "Terminate the program")

        #------- Creating the menu.
        # create a new instance of the wx.MenuBar() object
        menubar = wx.MenuBar()
        # add our filemenu as the first thing on this menu bar
        menubar.Append(filemenu,"&File")
        # set the menubar we just created as the MenuBar for this frame
        self.SetMenuBar(menubar)
        #----- Setting menu event handler
        wx.EVT_MENU(self,ID_EXIT,self.OnExit)

        self.Show(True)

    def OnExit(self,event):
        self.Close(True)

    def OnClick(self,event):
        #SECOND EDIT: added try: statement to the next line:
        try:
            if not self.dialog:
                self.dialog = wx.ProgressDialog("Progress in processing your data.", self.newStep,
                                            self.progressMax,
                                            style=wx.PD_CAN_ABORT
                                            | wx.PD_APP_MODAL
                                            | wx.PD_SMOOTH)
            self.count += 1
            self.newStep='Start'
            (keepGoing, skip) = self.dialog.Update(self.count,self.newStep)
            TestID = self.edithear.GetValue()

            self.count += 1
            self.newStep='Continue.'
            (keepGoing, skip) = self.dialog.Update(self.count,self.newStep)
            myObject=myClass(TestID)
            print myObject.description

            self.count += 1
            self.newStep='Finished.'
            (keepGoing, skip) = self.dialog.Update(self.count,self.newStep)

            **#FIRST EDIT: Added self.count = 0 on the following line**
            self.count = 0

            self.dialog.Destroy()

        #SECOND EDIT: Added the next seven lines to handle exceptions.
        except:
            self.dialog.Destroy()
            import sys, traceback
            xc = traceback.format_exception(*sys.exc_info())
            d = wx.MessageDialog( self, ''.join(xc),"Error",wx.OK)
            d.ShowModal() # Show it
            d.Destroy() #finally destroy it when finished


    class myClass():
        def __init__(self,TestID):
            self.description = 'The variable name is:  '+str(TestID)+'. '

app = wx.PySimpleApp()
frame = MainWindow(None,-1,"My GUI")
app.MainLoop()

My actual code is A LOT more complex, but I created this dummy version of it to illustrate the problems with it. This code above works when I run it in python the first time I click the button. But if I try to click the button a second time, I get the following error message in the python shell:

Traceback (most recent call last):
  File "mypath/GUIdiagnostics.py", line 55, in OnClick
    (keepGoing, skip) = self.dialog.Update(self.count,self.newStep)
  File "C:\Python26\lib\site-packages\wx-2.8-msw-unicode\wx\_windows.py", line 2971, in Update
    return _windows_.ProgressDialog_Update(*args, **kwargs)
wx._core.PyAssertionError: C++ assertion "value <= m_maximum" failed at ..\..\src\generic\progdlgg.cpp(337) in wxProgressDialog::Update(): invalid progress value

FIRST EDIT: OK, I answered my first question above by adding

self.count = 0

above

self.dialog.Destroy()

in the code above. But what about my second question regarding error handling in the code above? Can anyone help me with that? Surely, error handling in wxpython is a common issue for which there are known methods. I am going to use py2exe to wrap this application up into an exe file.


SECOND EDIT: I answered my second question above with the try: , except: statement that I have added to my code above. Funny, this is the first time that no one on stack overflow has been able to answer my question. I am new to this type of programming, so a lot of things I am just picking up as they come. This question is now answered.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文