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

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 #################################################################


 类似资料:
  • 等待队列 到目前为止,我们的实验中,用户进程或内核线程还没有睡眠的支持机制。在课程中提到用户进程或内核线程可以转入等待状态以等待某个特定事件(比如睡眠,等待子进程结束,等待信号量等),当该事件发生时这些进程能够被再次唤醒。内核实现这一功能的一个底层支撑机制就是等待队列wait_queue,等待队列和每一个事件(睡眠结束、时钟到达、任务完成、资源可用等)联系起来。需要等待事件的进程在转入休眠状态后插

  • 等待队列接口 结构体 struct   rt_wqueue   等待队列控制块 更多...   struct   rt_wqueue_node   等待队列节点 更多...   宏定义 #define  RT_WQ_FLAG_CLEAN   0x00   等待队列清除   #define  RT_WQ_FLAG_WAKEUP   0x01   等待队列唤醒   #define  DEFINE_WA

  • 问题内容: Linux中有等待队列为FIFO的锁吗?这似乎是一件显而易见的事情,但是我刚刚发现pthread互斥锁不是FIFO,信号量显然也不是FIFO(我正在研究内核2.4(家庭作业))… Linux是否具有带有FIFO等待队列的锁,或者是否有简单的方法可以利用现有机制来建立锁? 问题答案: 这是创建基于pthreads原语的简单排队“票证锁”的方法。它应该给您一些想法:

  • 我有一个多线程应用程序,其中一个线程将项目放入< code>BlockingQueue中,多个线程从中取出项目进行处理。问题是关于从队列中获取项目,目前它是这样实现的: 根据<code>BlockingQueue的JavaDoc。take()它检索并删除队列的头部,如果需要,等待元素可用,对于<code>PriorityBlockingQueue直到队列中出现一个项目: 实现我们的逻辑的另一种方法

  • 问题内容: 我有两个分开的阻塞队列。客户端通常使用第二个阻塞队列中的第一个来检索要处理的元素。 在某些情况下,客户端对两个阻塞队列中的元素感兴趣,无论哪个队列首先提供数据。 客户端如何并行等待两个队列? 问题答案: 您可以尝试在某种循环中使用该方法,以仅在指定时间量内等待一个队列,然后再轮询另一个队列。 除此之外,我会说在另一个线程上为每个队列运行阻塞操作并为您的主应用程序提供回调接口是另一个稍微

  • 问题内容: 我正在将程序从Java转移到Objective C,需要使用在Java中经常用于线程化的wait和notify方法,但似乎在Objective C中找不到任何等效的方法。我尝试使用NSLock对象,但是我没有认为它没有用。(我正在使用[NSLock锁定]进行等待,并使用[NSLock解锁]进行通知)我无法找到的Objective C中有什么等效项吗? 问题答案: 您可以使用多种技术。您

  • 我启动了几个异步进程,如果需要,这些进程反过来可以启动更多的进程(想想遍历目录结构或类似的东西)。每个进程都会返回一些东西,最后我想等待所有这些进程的完成,并安排一个函数来处理结果集合。 我的解决方案尝试使用可变的(我不断添加我生成的期货)和来安排一些函数在此缓冲区中列出的所有这些期货完成后运行。 我准备了一个简单的例子来说明这个问题: 它首先调度和期货,然后将在1秒后的分辨率中调度。本身将在2秒

  • 如果我对如何使用RxJava2缺乏基本的了解,请提前道歉,因为在我看来,这应该是非常基本的东西。我已经因为不成功的Google搜索而绞尽脑汁,所以欢迎任何资源推荐。为了清晰起见,我选择使用解决方法代码的“净化”表示。 我有一个RxJava2函数,它返回一个