使用Python中的Tkinter创建进度条(ttk.Progressbar),但是进度条没有显示。

3
在Python中(在tkinter GUI中),使用ttk.Progressbar,我试图在按下按钮时显示进度条。 单击GUI上的“Analyse”按钮会调用脚本中的analyze函数,该函数被设计为类似于三阶火箭:

  1. grid() 进度条小部件以将其添加到主框架中,并启动它。

  2. 执行实际计算(在我的测试运行中需要大约三秒钟)

  3. stop() 进度条并用grid_remove() 将其隐藏,因为任务已完成。

如果注释掉步骤3,则进度条将按预期显示和启动,同时执行步骤2。但是,如果步骤三仍然存在,则首先不会显示进度条。由于步骤二中的工作无论如何都会执行,因此我认为这可能与在同一函数调用中对进度条小部件进行网格化和删除有关。但由于这是我在Python中的第一个真正的GUI项目,因此我有点迷茫,不知道如何解决这个问题(如果确实是问题)。 是否有一种方法可以绕过此问题或更优雅地完成相同的任务?按钮调用的函数如下:

def analyze():
    # --Step 1--
    progressbar.grid()
    progressbar.start()

    # --Step 2--
    global analysis
    analysis = analyzer.Analysis(file_path.get())
    analysis.output_to_file()

    # --Step 3--
    progressbar.stop()
    progressbar.grid_remove()

我希望能够通过贴出我界面的图片来更加清晰地解释,但由于我的声望分数目前不允许发布图片,所以我希望通过我的解释(和代码)已经足够清楚地说明了问题。

1个回答

4
为了让小部件在创建后出现,必须允许事件循环运行。这是因为小部件在屏幕上的实际绘制是作为重绘事件的结果发生的。
您可以调用update_idletasks,它将允许事件循环服务此类重绘事件,在创建和启动进度条之后。但是,在运行计算时,您的应用程序可能会看起来冻结。同样,这是因为必须允许事件循环服务事件,而在执行其他操作时无法做到这一点。
解决此问题的常规方法是在线程或单独的进程中运行长时间运行的计算。

1
顺便提一下,当不使用线程时,有时还需要手动调用根窗口的“update()”方法来强制发生任何其他挂起的重绘事件--例如,用于删除已解除的对话框框。 - martineau

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接