【问题标题】:Avoid tkinter GUI lock when using ttk.Progressbar使用 ttk.Progressbar 时避免 tkinter GUI 锁定
【发布时间】:2013-09-13 10:32:03
【问题描述】:

我正在尝试为长时间运行的东西编写 GUI,但似乎无法弄清楚如何避免锁定 GUI 线程。我想使用 ttk.Progressbar 但我似乎无法更新栏值并让窗口更新 GUI。我已经尝试将更新处理放在它自己的函数中并直接更新它,但都没有奏效。更新处理程序中的值是我更喜欢做的,因为这个脚本会做一些下载,然后处理,然后上传,三个单独的栏看起来最好。

from Tkinter import *
import time, ttk

class SampleApp(Frame):
    def __init__(self,master):
        Frame.__init__(self,master)
        self.pack()
        self.prog = ttk.Progressbar(self, orient = 'horizontal', length = 200, mode = 'determinate')
        self.prog.pack()
        self.button = Button(self,text='start',command=self.start)
        self.button.pack()

    def start(self):
        self.current = 0
        self.prog["value"] = 0
        self.max = 10
        self.prog["maximum"] = self.max
        self.main_prog()

    def handler(self):
        self.prog['value'] += 1

    def main_prog(self):
        for x in range(10):
            time.sleep(2)
            self.handler()

root = Tk()
app = SampleApp(master = root)
app.mainloop()

【问题讨论】:

  • 你考虑过使用线程吗?

标签: python locking tkinter progress-bar ttk


【解决方案1】:

导致锁定的不是进度条,而是您对time.sleep()的调用

GUI 工具包使用事件循环来处理用户输入。您正在使用 sleep 调用中断事件处理。

有几种方法可以在事件驱动程序中处理长时间运行的作业;

  1. 使用根窗口的after 方法将作业切成小块并在超时时处理每个小块。
  2. 在单独的线程中处理处理。请注意,这个线程应该调用 tkinter 函数!请注意,由于 GIL,在 cpython 中一次只能有一个线程处理字节码。
  3. 使用multiprocessing 在单独的进程中处理处理。使用队列将数据发送到该进程和从该进程发送数据。 GUI 程序从队列中读取并在超时时更新 GUI。

【讨论】:

  • 队列也可以在情况2中用于线程之间的通信。
  • 谢谢,我想我会选择#3。我可以在单独的进程中运行其他函数,并使用队列将更新调用传递回 GUI。现在我只需要弄清楚如何做到这一点。
猜你喜欢
  • 2018-05-03
  • 1970-01-01
  • 1970-01-01
  • 2020-07-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多