1

我想使用 wx.ProgressDialog 来显示我的程序的进度。我有一个按钮,按下时会运行此功能:

def runmiP(self, event):
    predictor.runPrediction(self.uploadProtInterestField.GetValue(), self.uploadAllProteinsField.GetValue(), self.uploadPfamTextField.GetValue(), \
                   self.edit_eval_all.Value, self.edit_eval_small.Value, self.saveOutputField)

predictor 是我写的一个 python 包。如何从预测器中获取进度并将其显示在进度条中?我只能返回一个值。我应该多次调用它(比如每分钟),记住它离开的位置,返回它有多远并再次调用它?就像是

while 1: 
    time.sleep(60)
    predictor.runPrediction(self.uploadProtInterestField.GetValue(), self.uploadAllProteinsField.GetValue(), self.uploadPfamTextField.GetValue(), \
                   self.edit_eval_all.Value, self.edit_eval_small.Value, self.saveOutputField)

还是有更好的方法来做到这一点?

4

1 回答 1

3

这是一个普遍的问题。(除非您已经在另一个线程上运行它,否则您会阻塞整个 UI,而不仅仅是无法更新进度条,对吗?)并且有两种通用方法可以解决它。

  • 将回调传递给 runPrediction,并使其progressCallback(sofar, total)在循环中每 X 次、每 Y% 或每 Z 秒调用一次。(您可以使用其他一些通信机制——发布到队列并触发条件、通过管道或套接字发送消息等——但想法是相同的。)

  • 将 runPrediction 分解为可以按顺序运行的单独的较小作业,并在每次开始下一个作业时更新进度。

您的解决方案基本上是第二个想法的稍微笨拙但通常完全合理的版本。如果没有明确的方法来分解工作,但有一种合理的方法可以中止工作,把它藏在哪里,然后再继续,这实际上与分解工作是一样的,对吧?

Python 提供了一种通常更简单、更简洁的方法来实现第二个想法:将 runPrediction 变成一个生成器,它会在结果进入时产生结果,而不是在最后返回所有结果。然后,您只需在每个值返回时更新进度。

于 2012-11-30T22:13:05.510 回答