使用计数器代替定时器的wx.ProgressDialog

0 投票
1 回答
1366 浏览
提问于 2025-04-16 06:12

我想在我的wxpython应用程序中加入一个进度条,但我找到的例子都是用定时器从固定的时间倒计时。因为我不知道具体的计算机运行我的程序需要多长时间,所以我希望进度条能在每一步完成时自动更新。

我修改了一些示例代码来实现这个功能,但它出现了以下错误:

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

当我在下面的代码中添加try...except语句时,错误就不再出现了,但我觉得这并不是解决问题的好办法,只是在错误信息上盖了一层遮羞布。

有没有人能教我怎么修复我的代码?

我的代码如下,包括“去掉”错误的try...except语句:

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

注意:我使用while循环来模拟处理步骤的执行,以便测试这段代码。但在实际应用中,我会在每次自增self.count之前,执行一个特定的处理步骤。

1 个回答

1

你的 progressMax 是 7,而循环的条件是 count 小于 8,但你在循环的第一行就增加了 count 的值,这样就会出现 count 等于 8 的情况,这对进度条来说是个不合法的值。

你可以把循环的条件改成 count < 7(其实可以写成 count < progressMax),或者把 count 的增加放到循环的最后面。

撰写回答