为什么在 Tkinter 中处理后会出现 ttk Progressbar [英] Why ttk Progressbar appears after process in Tkinter

查看:70
本文介绍了为什么在 Tkinter 中处理后会出现 ttk Progressbar的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想根据 Tkinter 菜单命令创建一个大文本,并通过进度条提供视觉支持.虽然进度条是在随后的耗时循环之前开始的,但只有在创建并显示大文本之后才会显示进度条.

I want to create a large text upon Tkinter menu command and provide visual support by a progress bar. Although the progress bar is meant to start before the subsequent time-consuming loop, the progress bar shows up only after the large text was created and displayed.

def menu_bar(self):
    self.create_menu.add_command(label="Create large file", 
    command=self.create_large_file)

def create_large_file(self):
    self.progressbar = ttk.Progressbar(self.master, mode='indeterminate')
    self.progressbar.pack()
    self.progressbar.start()
    self.text.delete(1.0, 'end')
    self.file_content = []

i = 0
while i < 2000000:
    line = lfd.input_string
    self.file_content.append(line + "\n")
    i += 1

self.file_content = ''.join(self.file_content)
self.text.insert(1.0, self.file_content) 

推荐答案

我认为问题是耗时的循环阻止了 tkinter 事件循环,mainloop(),从运行.换句话说,当您的工作密集型函数与 GUI 在同一线程中运行时,它会通过占用解释器来干扰它.

I think the problem is that the time-consuming loop is preventing the tkinter event loop, mainloop(), from running. In other words, when your work intensive function runs in the same thread as the GUI, it interferes with it by hogging the interpreter.

为了防止这种情况,您可以使用辅助 Thread 运行您的函数并在主线程中运行 GUI 及其进度条.为了让您了解如何执行此操作,这是我从另一个(不相关)progressbar question 中的代码派生的一个简单示例 来展示可以轻松完成这样的事情.注意: 通常建议不要让辅助线程直接访问主线程的 tkinter 对象.

To prevent this you can use a secondary Thread to run your function and run the GUI and its progressbar in the main thread. To give you an idea of how to do this, here's a simple example I derived from code in another (unrelated) progressbar question to show how easily something like that can be done. Note: It's generally recommended that secondary threads not be given direct access to the main thread's tkinter objects.

from Tkinter import *
import ttk

import time
import threading

def foo():
    time.sleep(5) # simulate some work

def start_foo_thread(event):
    global foo_thread
    foo_thread = threading.Thread(target=foo)
    foo_thread.daemon = True
    progressbar.start()
    foo_thread.start()
    root.after(20, check_foo_thread)

def check_foo_thread():
    if foo_thread.is_alive():
        root.after(20, check_foo_thread)
    else:
        progressbar.stop()

root = Tk()
mainframe = ttk.Frame(root, padding="3 3 12 12")
mainframe.grid(column=0, row=0, sticky=(N, W, E, S))
mainframe.columnconfigure(0, weight=1)
mainframe.rowconfigure(0, weight=1)
progressbar = ttk.Progressbar(mainframe, mode='indeterminate')
progressbar.grid(column=1, row=100, sticky=W)

ttk.Button(mainframe, text="Check",
           command=lambda:start_foo_thread(None)).grid(column=1, row=200,
                                                       sticky=E)

for child in mainframe.winfo_children():
    child.grid_configure(padx=5, pady=5)
root.bind('<Return>', start_foo_thread)

root.mainloop()

这篇关于为什么在 Tkinter 中处理后会出现 ttk Progressbar的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆