繁体   English   中英

在tkinter中使用sys.stdout.write(“\\ r \\ n ...”)

[英]Using sys.stdout.write(“\r…”) in tkinter

我有一个处理数千个小文件的小脚本。 该操作需要一段时间,因此程序将进度输出到控制台。 它在以下代码中模拟:

files = 5000 #Number of files
    for i in range(files):
        sys.stdout.write("\r{0} of {1}".format(i, files))

我喜欢这种输出进度的方式; 控制台中只打印一行。 但是现在我想从GUI(tkinter)运行这个脚本,我希望将输出打印到状态栏(标签)。 我现在有点亏本如何实现这一点。 有没有办法在不编辑脚本的情况下处理GUI中的输出?

虽然你可以截取stdout并随心所欲地做任何事情,但这是一个坏主意 - 即使你这样做,你的程序首先也没有意义。

您无法在GUI应用程序中运行“需要一段时间”的操作。 当操作正在运行时,GUI的主循环未运行,这意味着整个GUI被冻结。 除了给你一个沙滩球,这也意味着你做出的任何改变在你回来之前是不可见的。

如果你在另一个线程中执行操作怎么办? 那么,它不会阻止GUI运行...但你不能从任何线程但主线程与Tkinter小部件交谈,所以这没有帮助。

因此,您需要做的是一次执行一个操作步骤,每次将其余操作安排为稍后执行的回调。

例如:

class StatusWriter(object):
    def write(self, msg):
        statusbar.config(text=msg[1:])

def count():
    sys.stdout = StatusWriter()
    i = 0
    def step():
        nonlocal i
        sys.stdout.write("\r{} of {}".format(i, 50))
        i += 1
        if i == 50:
            sys.stdout = sys.__stdout__
        else:
            root.after(100, step)
    root.after(100, step)

但实际上,一旦你重写了一些东西,那么删除stdout替换hackery也更有意义:

def count():
    sys.stdout = StatusWriter()
    i = 0
    def step():
        nonlocal i
        statusbar.config(text="{} of {}".format(i, 50))
        i += 1
        if i == 50:
            sys.stdout = sys.__stdout__
        else:
            root.after(100, step)
    root.after(100, step)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM