如何使用wx.ProgressDialog
计算名为imgSearch
的方法? imgSearch
方法在用户的PC上查找图像文件。如何在wx.ProgressDialog
仍在运行时imgSearch
运行并显示imgSearch
正在服用多长时间?
这是我的代码:
def onFind (self,event)# triggered by a button click
max = 80
dlg = wx.ProgressDialog("Progress dialog example","An informative message",parent=self, style = wx.PD_CAN_ABORT| wx.PD_APP_MODAL| wx.PD_ELAPSED_TIME| wx.PD_REMAINING_TIME)
keepGoing = True
count = 0
imageExtentions = ['*.jpg', '*.jpeg', '*.png', '*.tif', '*.tiff']
selectedDir = 'C:\\'
imgSearch.findImages(imageExtentions, selectedDir)# my method
while keepGoing and count < max:
count += 1
wx.MilliSleep(250)
if count >= max / 2:
(keepGoing, skip) = dlg.Update(count, "Half-time!")
else:
(keepGoing, skip) = dlg.Update(count)
dlg.Destroy()
答案 0 :(得分:5)
您的问题很模糊,但在查看您的代码之后,我会猜测您的问题是imgSearch.findImages()
在对话框打开之前就完成了。如果你能编辑你的问题我会很感激,所以我知道这是否正确。
我发现您正在使用this tutorial中的代码向您展示如何使用wx.ProgressDialog
。不幸的是,你采取了一种相当天真的方法。该教程的目的是向读者介绍各种内置对话框。因此,wx.ProgressDialog
示例只是为了向您展示方法,而不是用作实现。
首先,您需要知道multithreading是什么以及它是如何工作的。计算机所做的一切都被分解为一系列数学运算。计算机处理器一次只能执行一个操作。因此,计算机一次只能做一个事物。现在你可能会想“那不是真的。我在浏览互联网时正在听MP3。这至少有两件事”。嗯,你是对的,你错了。想象一下厨师。厨师可以一次准备许多菜肴但他一次只能注意一个。因此,他必须在菜肴之间切换,执行一些小任务,直到它们全部完成。这就是计算机multitasks的方式。计算机不是“菜肴”,而是在“线程”之间切换。
默认情况下,wxPython只是一个单独的线程(这不完全正确,但只需使用它)。 wxPython逐字地逐行运行代码,这样一行必须在下一行运行之前完成。因此,在imgSearch.findImages()
运行时,没有其他代码正在执行,它必须在wx.ProgressDialog
甚至可以创建之前完成。好消息是,有几种方法可以解决这个问题。坏消息是修复这个问题会变得非常复杂。我不是专家,但我建议搜索“wxpython threading”并尝试查找一些教程。我找到了this tutorial,但它已经很老了。重点是您需要在其自己的线程中运行imgSearch.findImages()
,以便它不会阻止 GUI。
现在,您如何让wx.ProgressDialog
反映imgSearch.findImages()
的实际状态?嗯,这取决于。您需要找到一些指标,以帮助您衡量已完成的工作量以及剩下的工作量。在您的代码中,度量标准是时间,因为进度编程为80 * 250ms = 20s
。时间可能不是你想要的。您需要确定什么是最适合您的程序,但我将使用“文件夹数”的示例,因为它很容易理解。我会计算文件夹的总数以及我完全扫描的文件夹数。现在有两种方法可以初始化您的指标。如果数字很小或易于计算(例如时间),您可以计算所需的max
,或者您可以采用动态方法。在我的情况下,计算“文件夹数量”确实需要几乎与图像搜索本身一样多的时间,因此动态是最佳选择。因此,我会修改imgSearch.findImages()
,以便它保留已查看的文件夹数量以及扫描的文件夹数量(例如,如果我的起始位置有3个文件夹,我以3/0开头。我开始扫描第一个文件夹,其本身包含2个文件夹,所以我现在有5/0。每次我完全扫描文件夹时,我会在扫描文件夹的数量上加1,即扫描一个文件夹后为5/1。知道我扫描了多少个文件夹以及我要扫描的文件夹数量,我可以使用# of folders scanned / total # of folders
估算完成百分比。 1 / 5 = 0.20
,因此我估计我完成了20%(请注意,如果我扫描的下一个文件夹包含5个以上的文件夹,那么这个数字会自动减少到10%。这就是为什么我称之为20%的估计值)
所以现在我们应该在它自己的线程中有imgSearch.findImages()
,它应该能够估计完成它的距离。现在我们需要更新wx.ProgresDialog
。我最喜欢的解决这些问题的方法是使用pubsub库。基本上,imgSearch.findImages()
线程必须偶尔发送一条消息,说明它有多接近完成。也许在每个文件夹的末尾。也许有三个文件夹。由你决定。接下来,您需要在主GUI的线程中创建一个方法,该方法可以读取这些消息并相应地更新wx.ProgressDialog
。
这是很多工作,但我祝你好运。