Tkinter:如何使文本小部件上的字符出现延时?

时间:2017-11-10 17:11:58

标签: python tkinter

def write_text(widget, message, enter_number, slow_type=True):
    widget.config(state="normal")
    if slow_type:
        if len(message) > 0:
            widget.insert("insert", message[0])
        if len(message) > 1:
            widget.after(100, UI.write_text, widget, message[1:], 0)
    else:
        widget.insert("insert", message)

    for i in range(enter_number):
        widget.insert("insert", "\n")

    widget.config(state="disabled")
    widget.see("end")

这是我的代码,用于编写时间延迟中显示的每个字符

但我有一个问题:

如果我这样调用这个方法(我有一个名为text1的小部件)。

write_text(text1, ">>>Invalid Input", 1)
write_text(text1, ">>>Try Again...", 2)

消息将这些内容混合在一起>>>>>>ITnrvya lAigda iInn.p.u.t

我希望在输入上一条消息时输入消息。

我该怎么办?

P.S。抱歉我的英语不好......

1 个答案:

答案 0 :(得分:1)

这里有一些可以实现我认为你想要的东西。 "混合"你得到的输出是因为你需要write_text()的第二次调用在第一次完成所有(延迟)处理之前发生,所以文本小部件通过两个单独的回调过程有效地获得更新。

下面的代码通过在Queue中放置字符串的字符(以及它们在哪一行)来避免这个问题,这允许以与添加它们相同的顺序检索它们。

DELAY = 100  # ms between widget updates

def update_widget(widget):
    try:
        line_number, text = widget._text_queue.get_nowait()
    except queue.Empty:
        return  # Nothing further to do.

    widget.insert('%s.end' % line_number, text)

    if widget._text_queue.qsize():  # Anything more to process?
        widget.after(DELAY, update_widget, widget)

def write_text(widget, message, line_number, slow_type=True):
    if not slow_type:
        widget.insert('%s.0' % line_number, message)
    else:
        for ch in message:  # Add each character of message to queue.
            widget._text_queue.put((line_number, ch))

        update_widget(widget)  # Start (or continue) update processing.

def add_text(widget):
    widget.delete('1.0', tk.END)  # Delete widget's current contents.

    # Note: Tkinter always adds a newline at the very end of text widgets, so
    #    we need one less newline. This makes it possible to insert text onto
    #    any possible line of the widget -- which could fail if it was empty.
    widget.insert('1.0', (widget['height']-1) * '\n')  # Init with blank lines.
    write_text(widget, ">>>Invalid Input", 1)
    write_text(widget, ">>>Try Again...", 2)

if __name__ == '__main__':
    root = tk.Tk()
    text1 = tk.Text(root, width=40, height=3, bg='skyblue')
    text1._text_queue = queue.Queue()  # Add a Queue to it for delayed updates.
    text1.grid()
    button = tk.Button(root, text='Run Test', command=lambda w=text1: add_text(w))
    button.grid()
    root.mainloop()