如何使用我自己的方法使用`wx.ProgressDialog`?

use*_*950 2 python user-interface wxpython

我如何使用wx.ProgressDialog时间调用我的方法imgSearch?该imgSearch方法在用户的PC上查找图像文件.如何wx.ProgressDialogimgSearch仍在运行时进行运行并显示需要多长时间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()
Run Code Online (Sandbox Code Playgroud)

aca*_*tle 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.

这是很多工作,但我祝你好运.