views:

26

answers:

1

I need to include a progress bar in my wxpython application, but the examples I found use a timer counting down from a fixed time length. Since I have no idea how long it will take a given computer to run my process, I want the progress bar to simply update whenever each specific step is completed.

I modified some sample code to accomplish this, but it throws the following error:

path/ProgressDialog.py", line 31, in OnTimer
    (keepGoing, skip) = self.dialog.Update(self.count)
File "C:\Python26\lib\site-packages\wx-2.8-msw-unicode\wx\_windows.py", line 2971, in Update
return _windows_.ProgressDialog_Update(*args, **kwargs)
PyAssertionError: C++ assertion "value <= m_maximum" failed at ..\..\src\generic\progdlgg.cpp(337) in wxProgressDialog::Update(): invalid progress value

When I add the try...except statement in the code below, it does not throw the error, but I am thinking that there must be a better way of doing this than simply drawing a fig leaf over the error message.

Can anyone show me how to fix my code?

My code is as follows, including the try...except statement that "removes" the error:

import wx
import time

class Frame(wx.Frame):
    def __init__(self, parent):
        wx.Frame.__init__(self, parent, title="ProgressDialog sample")
        self.progressMax = 7
        self.count = 0
        self.dialog = None
        #self.timer = wx.Timer(self)
        #self.Bind(wx.EVT_TIMER, self.OnTimer, self.timer)
        #self.timer.Start(1000)
        self.OnTimer(self.count)

    def OnTimer(self, evt):
        try:
            if not self.dialog:
                self.dialog = wx.ProgressDialog("A progress box", "Time remaining",
                                                self.progressMax,
                                                style=wx.PD_CAN_ABORT
                                                | wx.PD_ELAPSED_TIME
                                                | wx.PD_REMAINING_TIME
                                                | wx.PD_ESTIMATED_TIME
                                                | wx.PD_AUTO_HIDE)

            while self.count < 8:
                self.count += 1
                if wx.VERSION < (2,7,1,1):
                    keepGoing = self.dialog.Update(self.count)
                else:
                    (keepGoing, skip) = self.dialog.Update(self.count)
                time.sleep(2)
            if not keepGoing or self.count == self.progressMax:
                self.dialog.Destroy()
                #self.timer.Stop()
        except:
            pass

if __name__ == "__main__":
    app = wx.PySimpleApp()
    frame = Frame(None)
    frame.Show()
    app.MainLoop()

Note: I am using a while loop to simulate stepping through process steps while I am testing this code. But in the actual implementation, I will have a specific process step occur before each time that self.count is increased by 1.

A: 

Your progressMax is 7 and the loop loops while count is less than 8, but you increment count on the first line of the loop so you have an iteration where count is 8 and that is an illegal value for the progress bar.

Either change the while condition to count < 7 (conveniently count < progressMax) or move the count increment to the end of the loop.

Toni Ruža