fle*_*bas 4 multithreading tkinter
我有代码应该显示 tkinter 小部件(注意:尚未实现)和另一个线程之间的通信。作为这两者之间的通信,我选择 python 队列。要查看真正发生的事情,控制台中会显示打印,这不是我所期望的。
如可以在控制台输出可以看出在睡眠时间后generate_text输出从process被示出。我的预期是,由于generate_text是慢然后process我会看到更多的process is called,然后Item x,但这没有发生。
import tkinter as tk
import threading
import queue
import time
def generate_text(storage):
count = 0
while True:
message = "Item {}".format(count)
storage.put(message)
print(message)
count +=1
time.sleep(3000/1000)
def process(storage):
print("process is called")
try:
storage.get()
except queue.Empty:
print("queue empty")
# register awake function
root.after(500, process, message)
# init variables
message = queue.Queue()
root = tk.Tk()
t = threading.Thread(target=generate_text, args=(message,))
t.setDaemon(True)
t.start()
root.after(500, process, message)
root.mainloop()
Run Code Online (Sandbox Code Playgroud)
输出:
import tkinter as tk
import threading
import queue
import time
def generate_text(storage):
count = 0
while True:
message = "Item {}".format(count)
storage.put(message)
print(message)
count +=1
time.sleep(3000/1000)
def process(storage):
print("process is called")
try:
storage.get()
except queue.Empty:
print("queue empty")
# register awake function
root.after(500, process, message)
# init variables
message = queue.Queue()
root = tk.Tk()
t = threading.Thread(target=generate_text, args=(message,))
t.setDaemon(True)
t.start()
root.after(500, process, message)
root.mainloop()
Run Code Online (Sandbox Code Playgroud)
@Himal 的答案对于当前问题是正确的,但是您可能希望修改它以event_generate在消息生成代码中使用,并让 UI 在事件发生时响应事件,而不是像这样轮询队列。您可以root.event_generate('<<MessageQueued>>')在generate_text功能中使用将虚拟事件放置到 Tk 的事件队列中。这是线程安全的,直接调用窗口方法不是。如果您还在 UI 代码上添加到此虚拟事件的绑定,则 Tk 消息循环会在收到虚拟事件时调用绑定函数。不再进行投票。
import tkinter as tk
import threading
import queue
import time
def generate_text(mainwin, storage):
count = 0
while True:
message = "Item {}".format(count)
storage.put(message)
print("Queued {0}".format(message))
count += 1
mainwin.event_generate('<<MessageGenerated>>')
time.sleep(3000/1000)
def process(storage, event):
msg = storage.get()
print("New message: {0}".format(msg))
def main():
message_queue = queue.Queue()
root = tk.Tk()
root.bind('<<MessageGenerated>>', lambda e: process(message_queue, e))
t = threading.Thread(target=generate_text, args=(root, message_queue,))
t.setDaemon(True)
t.start()
root.mainloop()
if __name__ == '__main__':
main()
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1071 次 |
| 最近记录: |