Python Tkinter如何在for循环中更新文本小部件?

时间:2019-10-06 22:35:20

标签: python-3.x tkinter

我正在尝试在for循环内的scrolltext小部件中更新文本。每次循环时,print语句都会显示更新的文本,但是直到循环完成,我在Tk窗口中看不到任何内容。然后我看到 '('这是',4,'通过循环的次数。')'。 我从没看到0到3的显示。

from   tkinter import *
from   tkinter import scrolledtext
import time

main = Tk()
main.title("test_loop")
main.geometry('750x625')
main.configure(background='ivory3')


def show_msg():
    global texw
    textw = scrolledtext.ScrolledText(main,width=40,height=25)
    textw.grid(column=0, row=1,sticky=N+S+E+W)
    textw.config(background="light grey", foreground="black",
             font='arial 20 bold', wrap='word', relief="sunken", bd=5)
    for i in range(5):
        txt = "This is ", i, " times though the loop."
        txt = str(txt)
        print(txt)
        textw.delete('1.0', END)  # Delete any old text on the screen
        textw.update()            # Clear the screen.
        textw.insert(END, txt)    # Write the new data to the screen
        time.sleep(5)

btn = Button(main, text = 'display_log', bg='light grey', width = 15, 
         font='arial 12', relief="raised",bd=5,command = show_msg)
btn = btn.grid(row = 0, column = 0)

main.mainloop()

3 个答案:

答案 0 :(得分:1)

首先让我们清理代码使其对PEP8更友好,同时还要更改导入,因此我们不导入*。通过导入*,您将面临覆盖导入和内置方法的风险。

我将在函数外创建小部件,然后将包含sleep()的循环替换为可以调用自身并使用after()的函数,因为睡眠会阻塞主循环,从而使GUI无效并冻结,直到所有的睡眠都完成了。 after()用于避免此问题。

import tkinter as tk
from tkinter import scrolledtext

root = tk.Tk()
root.title('test_loop')
root.geometry('750x625')
root.configure(background='ivory3')
textw = scrolledtext.ScrolledText(root, width=40, height=25)
textw.grid(column=0, row=1, sticky='nsew')
textw.config(background='light grey', foreground='black', font='arial 20 bold', wrap='word', relief='sunken', bd=5)


def show_msg(count=None):
    if count is not None:
        if count <= 5:
            txt = 'This is {} times though the loop.'.format(count)
            textw.delete('1.0', 'end')
            textw.insert('end', txt)
            count += 1
            root.after(2000, lambda: show_msg(count))
    else:
        show_msg(1)


tk.Button(root, text='display_log', bg='light grey', width=15, font='arial 12', relief='raised', bd=5,
          command=show_msg).grid(row=0, column=0)

root.mainloop()

结果:

enter image description here

如果您希望将所有日志保留在屏幕上(假设您想照常保留所有日志),我将删除命令,然后在文本中添加\n,以便打开每个日志新行。

像这样简单地编辑函数:

def show_msg(count=None):
    if count is not None:
        if count <= 5:
            txt = 'This is {} times though the loop.\n'.format(count)
            # textw.delete('1.0', 'end')
            textw.insert('end', txt)
            count += 1
            root.after(2000, lambda: show_msg(count))
    else:
        show_msg(1)

结果:

enter image description here

如果您有任何疑问,请告诉我。

答案 1 :(得分:0)

问题在于,直到循环运行,窗口才会更新。为了避免“释放​​”,您应该定期更新它。做这样的事情:

from tkinter import *
do_your_init()
tk = Tk()
do_your_preparation()
for x in range(n):
    do_your_update()
    tk.update()

希望有帮助!祝你好运!

答案 2 :(得分:0)

在插入文本之后,然后在下次调用 N = 20 T = sym.Matrix(N,N, lambda n,r:Tfin(n,r)) T N = 20 V = sym.Matrix(N,N, lambda n,r:VFunc(n+1,r+1)) V H = T + V H 之前删除文本,您正在睡眠。对update的调用需要在插入文本之后而不是之前进行。