【问题标题】:Make Tkinter force a "refresh" a text widget in mid-command?让 Tkinter 在命令中强制“刷新”文本小部件?
【发布时间】:2018-06-17 03:48:26
【问题描述】:

我有一个 Tkinter 根目录,其中包含一个文本小部件以及其他项目。

当某个按钮被按下时,它被配置为 command= 以运行某个功能,当然。

在该函数中有一个 for 循环,它对文本小部件进行 10 次 快速 刷新。我什至在每次刷新之间放了一个 time.sleep(0.1),这样就不会太快了。

但是,当我运行它并按下那个按钮来触发这一切时,我只看到所有发生的时间滞后,然后最终的结束结果最终显示在框中。

如何在快速循环中强制它刷新文本小部件的内容?

我将在下面粘贴完整的应用程序。您可以看到,您看到的第一个函数是快速刷新文本小部件的函数……它被称为 dummycommand。谢谢! --eric

from tkinter import *
import tkinter.messagebox   
from random import *
import time

def dummycommand():
    for r in range (10):
        textoutput.delete(0.0, END)
        textoutput.insert(END,"|"*randint(1,10))
        time.sleep(0.1)   # THIS IS WHERE I WISH I COULD HAVE IT FORCE A REFRESH OF THE TEXT BOX

def hibox():
    tkinter.messagebox.showinfo("About EricOwn", "Tk-Try-Grid2 was designed and written in 2018 after a long"
                                                 " but not quite as bad research period where"
                                                 " we are not certain of the outcome.")
def roll():
    textoutput.delete(0.0,END)
    textoutput.insert(END,str(randint(1,1000)), 'tag-center')

def quitto():
    root.quit()

root=Tk()
root.wm_title("GridGlob Manager v0.9")

textoutput = Text(root,width=5,height=1,bd=20, background="light blue",font=("Helvetica", 36))
textoutput.tag_configure('tag-center', justify='center')

buttonroll = Button(root,text="Roll the dice", command=roll, activeforeground="blue",
                 activebackground="red",background="green",foreground="orange",padx=50)

buttonchars = Button(root,text="Show the chars", command=dummycommand, activeforeground="orange",
                 activebackground="blue",background="yellow",foreground="light blue",padx=50)

label1 = Label(root,text=" ")

radiobutton_widget1 = Radiobutton(root,text="Radiobutton 1", value=1)
radiobutton_widget2 = Radiobutton(root,text="Radiobutton 2", value=2)

label2 = Label(root,text=" ")


buttonq=Button(text="Info", command=hibox)
buttonr=Button(text="Quit", command=quitto)



# === Just the pulldown menus

menubar = Menu(root)
#=====
filemenu = Menu(menubar)
filemenu.add_command(label="About EricOwn", command=hibox)
filemenu.add_separator()
filemenu.add_command(label="Quit",command=root.quit, accelerator="Ctrl+Q")
menubar.add_cascade(label="File", menu=filemenu)
#=====
mathmenu = Menu(menubar)
mathmenu.add_command(label="Randomness", command=roll)
mathmenu.add_command(label="Multiplication",command=dummycommand)
mathmenu.add_command(label="Dancing",command=dummycommand)
mathmenu.add_command(label="Turtles",command=dummycommand)
mathmenu.add_command(label="Trip to Ireland",command=dummycommand)
mathmenu.add_command(label="Sandwich with good sourdough",command=dummycommand)
mathmenu.add_command(label="Western trot",command=dummycommand)
mathmenu.add_separator()
mathmenu.add_command(label="English",command=dummycommand)
mathmenu.add_command(label="Social Studies",command=dummycommand)
mathmenu.add_command(label="Geometry",command=dummycommand)
mathmenu.add_command(label="Guess it!",command=dummycommand)
menubar.add_cascade(label="Math", menu=mathmenu)





# === Now grid them

root.config(menu=menubar)

textoutput.grid(row=10, column=0, columnspan=2)
buttonroll.grid(row=20, column=0)
buttonchars.grid(row=20,column=1)

label1.grid(row=30)

radiobutton_widget1.grid(row=40, column=0, columnspan=2)
radiobutton_widget2.grid(row=50, column=0, columnspan=2)

label2.grid(row=60)

buttonq.grid(row=70, column=0)
buttonr.grid(row=70, column=1)

root.grid_columnconfigure(0, minsize=200)
root.grid_columnconfigure(1, minsize=200)

root.mainloop()

【问题讨论】:

    标签: tkinter


    【解决方案1】:

    time.sleep 正在阻止所有进程并冻结您的 GUI。请改用root.after

    def dummycommand():
        textoutput.delete(0.0, END)
        textoutput.insert(END, "|" * randint(1, 10))
        root.after(100, dummycommand)
    

    为了限制重复次数,可以使用关键字参数,带有默认值:

    def dummycommand(n_times=0, default=10):
        n = n_times + 1
        if n <= default:
            textoutput.delete(0.0, END)
            textoutput.insert(END, "|" * randint(1, 10))
            root.after(100, dummycommand, n)
    

    【讨论】:

    • 嗯——这是一个很好的输入,但它似乎只工作了一半。我将其更改为 0.1 秒,并插入了这一行: root.after(100, dummycommand) ... 但是,发生的情况是:也许前 5 次迭代,它很好地快速更新了文本框。但随后它在其中 5 个之后冻结,整个 tkinter/python 应用程序在我的 Mac 上冻结,显示彩虹球,我必须强制退出该应用程序。有什么想法吗? :) 谢谢--
    • 你应该用我的答案替换你的函数dummycommand ;只要您仍然拨打time.sleep,插入一行就不会起作用
    • 对不起,我应该解释得更好。我确实用你的线路替换了 sleep 命令。因为我明白是睡眠导致了问题。 ... ug,那么,对为什么会发生冻结有任何想法吗?
    • 不,我没有提供“一条线”,而是替代您的整个功能。如果将root.after 放在循环中,它将不起作用!
    • 噢噢!!对不起!!我需要更仔细地看这些东西!让我试一试,非常感谢 - eric
    猜你喜欢
    • 2017-08-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-11-27
    • 1970-01-01
    相关资源
    最近更新 更多