当前位置: 首页 > 面试题库 >

Tkinter:等待队列中的项目

宇文智敏
2023-03-14
问题内容

我正在使用队列在后台线程和Tk GUI应用程序之间交换消息。当前,这是通过不时调用查询方法来完成的。

def read_queue(self):
    try:
        self.process(self.queue.get(False)) # non-blocking
    except Queue.Empty:
        pass
    finally:
        self.after(UPDATE_TIME, self.read_queue)

这种方法的问题在于,如果UPDATE_TIME太大,应用程序将处理新项目的速度比可能的慢。如果太小,尽管Tk同时可以执行其他操作,但Tk会花费大部分时间检查队列。

是否有一种方法可以read_queue在新项目到达队列时自动触发该方法?(当后台线程填满队列时,我当然可以在Tk上调用方法,但我担心这会给我带来一些并发问题-
这就是为什么我始终使用队列。)


问题答案:

简介:我不会使用“ noob oddy的示例代码”
-这是一种根本有缺陷的方法。

我不是python专家,但是“ noob oddy”(在后台线程中调用root.event_generate(…))提供的示例代码似乎是“有根本缺陷的方法”。即,互联网上有几篇文章指出“从不在“
GUI线程”(通常是主线程)的上下文之外调用Tkinter函数/对象方法”。他的示例在大多数情况下都有效,但是,如果增加事件发生率,则示例的“崩溃率”将增加-
但是,特定行为取决于事件发生率和平台的性能特征。

例如,如果您进行更改,则将他的代码与Python 2.7.3结合使用:

       time.sleep(1)

至:

       time.sleep(0.01)

那么脚本/应用通常会在“ x”次迭代后崩溃。

经过大量搜索后,如果您“必须使用Tkinter”,则看来将“信息从后台线程获取到GUI线程”的最“防弹方法”是使用“
after()”小部件方法来轮询线程安全对象(例如“队列”)。例如,

################################################################################
import threading
import time
import Queue
import Tkinter      as Tk
import Tkconstants  as TkConst
from ScrolledText import ScrolledText
from tkFont       import Font

global top
global dataQ
global scrText

def thread_proc():
    x = -1
    dataQ.put(x)
    x = 0
    for i in xrange(5):
        for j in xrange(20):
            dataQ.put(x)
            time.sleep(0.1)
            x += 1
        time.sleep(0.5)
    dataQ.put(x)

def on_after_elapsed():
    while True:
        try:
            v = dataQ.get(timeout=0.1)
        except:
            break
        scrText.insert(TkConst.END, "value=%d\n" % v)
        scrText.see(TkConst.END)
        scrText.update()
    top.after(100, on_after_elapsed)

top     = Tk.Tk()
dataQ   = Queue.Queue(maxsize=0)
f       = Font(family='Courier New', size=12)
scrText = ScrolledText(master=top, height=20, width=120, font=f)
scrText.pack(fill=TkConst.BOTH, side=TkConst.LEFT, padx=15, pady=15, expand=True)
th = threading.Thread(target=thread_proc)
th.start()
top.after(100, on_after_elapsed)
top.mainloop()
th.html" target="_blank">join()
## end of file #################################################################


 类似资料: