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。抱歉我的英语不好......
答案 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()