简体   繁体   English

使用 tkinter 刷新,文本输出缓慢

[英]flush using tkinter, text output slowly

i was wondering if it would be possible to output text slowly using tkinter and a label我想知道是否可以使用 tkinter 和标签缓慢输出文本

the main problem is I don't know how to get it to flush.主要问题是我不知道如何让它冲洗。 I press the button, and then it waits 9 seconds, then it prints the whole thing.我按下按钮,然后它等待 9 秒,然后它会打印整个内容。

How do i get this to work with a flush i've tried label1.flush(), but it gives me an error also sys.stdout.flush() does't work, but it makes sense because this is to the console我如何让它与冲洗一起工作我试过 label1.flush(),但它给了我一个错误 sys.stdout.flush() 也不起作用,但这是有道理的,因为这是到控制台

def clicked():
    txt = "hello world"
    a = txt[0]
    label1 = tk.Label(window,text=a)
    label1.place(x=60,y=30)
    time.sleep(9)
    b = txt[1]
    c = a+b
    label1 = tk.Label(window,text=c)
    label1.place(x=60,y=30)

You should not use time.sleep with tkinter as it blocks the GUI processing.您不应将time.sleeptime.sleep一起使用,因为它会阻止 GUI 处理。 This causes it to print the whole thing in one go.这会导致它一次性打印整个内容。 Flushing is not possible because this is a Tkinter GUI, not a console, so there is no stdout to flush.刷新是不可能的,因为这是一个 Tkinter GUI,而不是一个控制台,所以没有要刷新的标准输出。 Instead, you have to do something like this:相反,您必须执行以下操作:

import tkinter as tk

def clicked():
    n = 0
    txt = "hello world"
    showChar(n, txt)

def showChar(n, txt):
    n += 1
    label.config(text = txt[:n])
    if n < len(txt):
        root.after(9000, lambda: showChar(n, txt))

root = tk.Tk()
label = tk.Label(root, text = "")
label.pack()
button = tk.Button(root, text = "Start", command = clicked)
button.pack()
root.mainloop()

When the button is clicked, the counter is initialised (set to 0) and the text is set.单击按钮时,计数器被初始化(设置为 0)并设置文本。 Then showChar is called.然后调用showChar This function increments the counter, then updates the label text to show an extra character.此函数增加计数器,然后更新标签文本以显示额外的字符。 If the string hasn't been full displayed yet, it waits 9000ms (or 9 seconds) until it runs itself again, using the tkinter method root.after .如果字符串还没有完全显示,它会等待 9000 毫秒(或 9 秒),直到它再次运行,使用root.after方法root.after This then works as you want it to.然后这会按您的意愿工作。

Here is a way to do this using .after loops:这是一种使用.after循环执行此操作的方法:

from tkinter import Tk, Label


def print_slow(widget: Label, text, delay: 'in miliseconds', index=1, start_index=0):
    widget.config(text=text[start_index: index])
    index += 1
    return root.after(delay, print_slow, widget, text, delay, index) if index <= len(text) else None


root = Tk()

label = Label(root, text='')
label.pack()

print_slow(label, 'hello world', 2000)

root.mainloop()

So pretty simple:非常简单:
First import only what You need, don't use wildcard ( * )首先只导入您需要的内容,不要使用通配符 ( * )

Second define the function, it will take arguments such as the widget to which it is needed to print slowly, then the text that has to be printed, then delay in milliseconds between characters appearing on the screen, then the end index and start index.第二个定义函数,它将接受参数,例如需要缓慢打印的小部件,然后是必须打印的文本,然后是屏幕上出现的字符之间的延迟(以毫秒为单位),然后是结束索引和开始索引。

Then simple tkinter stuff:然后是简单的 tkinter 东西:
.config() the widget's text attribute to the text from start_index to the end index .config()将小部件的文本属性设置为从start_index到结束index的文本
Then increment the end index by one然后将结束index加一
Then use .after() to schedule the same function (loop) after the given delay and pass the incremented index argument然后使用.after()在给定的delay之后调度相同的函数(循环)并传递递增的index参数

Then the simple tkinter stuff and also remember to initially call the function然后是简单的tkinter东西,还记得最初调用该函数

EDIT: updated the function to actually stop when finished, used some ternary conditions to return None (basically stop in this case) if the index is bigger than the lenght of the text编辑:更新函数以在完成时实际停止,如果index大于文本的长度,则使用一些三元条件return None (在这种情况下基本上停止)

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

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