2012-11-30 38 views
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) 

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

回答

2

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

  • 传递一个回调runPrediction,并使其循环时,每个Y%,或每ž秒叫progressCallback(sofar, total)每隔X倍。 (您可以使用其他通信机制 - 发布到队列并激发条件,通过管道或套接字发送消息等 - 但这个想法是相同的。)

  • 将run run预测分成更小的可以按顺序运行的作业,并在每次开始下一个作业时更新进度。

你的解决方案基本上是一个稍微笨拙的,但往往是完全合理的第二个想法的版本。如果没有明确的方法来打破这项工作,但是有一种合理的方式来放弃工作,存放它的位置,并在稍后恢复,这与打破工作实际上是一回事,对吗?

Python提供了一种更简单更清晰的方法来完成第二个想法:将runPrediction转换为生成器,在进入时生成结果,而不是在最后返回所有结果。然后,您只需在每个值返回时更新进度。

+0

回调并不总是有效,因为它不会运行允许进度UI重新绘制自己的消息循环。 –

+0

@MarkRansom:我已经在第一段中提到:“除非你已经在另一个线程上运行它,否则你会阻止你的整个UI,而不是无法更新进度条。 – abarnert

+0

对不起,这听起来像你说回调是解决这个问题。 –