在编写时更新Tkinter文本小部件,而不是在课程结束后更新 [英] Update a Tkinter text widget as it's written rather than after the class is finished

查看:69
本文介绍了在编写时更新Tkinter文本小部件,而不是在课程结束后更新的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我处于绑定状态,因为这是在机密计算机上编写的,因此我无法在此处复制粘贴。

I'm in a bind, since this is being written on a classified machine I am unable to copy+paste here. Being somewhat a novice, my approach is probably unorthodox.

我有一个用Tkinter编写的GUI,带有几个按钮。每个按钮都链接到一个实际上运行简短脚本的类。单击该按钮时,我将初始化一个类 log_window ,该类只是一个Tkinter文本小部件。然后,我创建一个全局变量,将 log 链接到我刚刚创建的 log_window ,并在脚本运行时通过管道传递 sys.stdout / stderr log (我专门为此创建了一个写方法)。除了 log_window 文本小部件,直到类调用完成后,该小部件才会使用管道标准输出进行更新,因此一切正常。但是,如果我只是在类中 print ,它将按照调用的顺序打印。

I have a GUI written in Tkinter with several buttons. Each button is linked to a class that, in effect, runs a short script. When the button is clicked, I inititalize a class log_window which is simply a Tkinter text widget. I then create a global variable linking log to the log_window I just created, and as the script runs I pipe sys.stdout/stderr to log (I created a write method specifically for this). Everything is kosher, except that the log_window text widget doesn't update with my piped stdout until after the class calling it is finished. However, if I simply print within the class, it will print in the order it is called.

示例

import Tkinter
from Tkinter import *
import time

class log_window:
    def __init__(self,master):
        self.textframe = Tkinter.Frame(master)
        self.text = Text(self.textframe)
        self.text.pack()
        self.textframe.pack()
    def write(self,text):
        self.text.insert(END,text)

class some_func1: # This effectively waits 5 seconds then prints both lines at once
    def __init__(self,master):
        log.write("some text")
        time.sleep(5)
        log.write("some text")

class some_func2: # This prints the first object, waits 5 seconds, then prints the second
    def __init__(self,master):
        print "some text"
        time.sleep(5)
        print "some text"

if __name__ == '__main__':
    global log    
    root = Tk()
    log = log_window(root)
    root.after(100,some_func1, root)
    root.after(100,some_func2, root)
    root.mainloop()

对不起,如果我的例子是有点闷闷不乐,但我认为这很重要。我所做的传递是通过 Popen 和一些系统调用来进行的,但是它们不是问题的一部分,所以我只强调了我认为是问题的LCD的原因。

Sorry if my example is a little bit muffed, but I think it makes the point. The piping I do is through Popen and some system calls, but they aren't part of the issue, so I only highlighted what, I presume, is the LCD of the issue.

推荐答案

我不知道Tkinter并发的详细信息,但四处逛逛表明如果您放进去

I don't know the details of Tkinter's concurrency, but fiddling around reveals that if you put

master.update_idletasks()

在每次调用 log.write 之后,它会根据提示进行更新。您可以给log一个 .flush()方法来做到这一点(就像文件句柄一样),或者您可以使 log.write 写入后调用它。

after each call to log.write, it updates on cue. You could give log a .flush() method to do that (like file handles have), or you could just make log.write call it after writing.

这篇关于在编写时更新Tkinter文本小部件,而不是在课程结束后更新的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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