2

如何使用wx.ProgressDialog我的方法调用的时间imgSearch?该imgSearch方法在用户的 pc 上查找图像文件。如何在仍在运行的wx.ProgressDialog同时进行运行并显示需要多长时间?imgSearchimgSearch

这是我的代码:

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

1 回答 1

5

问题

您的问题含糊不清,但在查看您的代码后,我猜您的问题是imgSearch.findImages()在对话框甚至打开之前就完成了。如果您可以编辑您的问题,我将不胜感激,以便我知道这是否正确。

我看到您正在使用本教程中的代码向您展示如何使用wx.ProgressDialog. 不幸的是,您对此采取了一种相当幼稚的方法。该教程的目的是向读者介绍各种内置对话框。因此,该wx.ProgressDialog示例是一个简单的示例,只是为了向您展示方法,而不是用作实现。

背景资料

首先,您需要了解什么是多线程以及它是如何工作的。计算机所做的一切都分解为一系列数学运算。计算机处理器一次只能执行一项操作。因此,计算机一次只能做一件事。现在您可能会想“这不是真的。我在浏览互联网时正在听 MP3。这至少是两件事”。好吧,你是对的,你错了。想象一个厨师。厨师可以一次准备很多菜,他一次只能注意一道菜。因此,他必须在菜肴之间切换,执行一些小任务,直到它们都完成。这就是计算机多任务处理的方式。而不是“菜”,

解决方案

第 1 步:穿线

默认情况下,wxPython 只是一个线程(这并不完全正确,但随它去吧)。wxPython 逐行运行您的代码,这样一行必须在下一行运行之前完全完成。因此,在imgSearch.findImages()运行时没有其他代码在执行,它必须在wx.ProgressDialog创建之前完成。好消息是有几种方法可以解决这个问题。坏消息是解决这个问题可能会变得相当复杂。我不是专家,但我建议搜索“wxpython threading”并尝试查找一些教程。我找到了这个教程,但它已经相当老了。要点是你需要imgSearch.findImages()在它自己的线程中运行,这样它就不会阻塞GUI。

第 2 步:指标

那么现在,您如何使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% 为估计值)

第 3 步:更新

所以现在我们应该有imgSearch.findImages()它自己的线程,它应该能够估计它离完成还有多远。现在我们需要更新wx.ProgresDialog. 对于这些类型的问题,我最喜欢的方法是使用pubsub库。基本上,imgSearch.findImages()线程必须偶尔发送一条消息,说明它有多接近完成。也许在每个文件夹的末尾。也许曾经三个文件夹。由你决定。接下来,您需要在主 GUI 线程中创建一个方法,该方法可以读取这些消息并wx.ProgressDialog进行相应更新。

工作量很大,但我祝你好运。

于 2012-09-03T03:26:05.997 回答