通过另一个过程在Tkinter GUI中更新Matplotlib图 [英] Updating matplotlib plot in tkinter gui via another process

查看:126
本文介绍了通过另一个过程在Tkinter GUI中更新Matplotlib图的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个使用 tkinter 编写的界面.在该界面内,我有一个 matplotlib 图.在后台,我让 zmq 连接到服务器以获取数据.我正在使用python的多处理模块,该模块具有共享数据的队列和正在为所有zmq通信运行的进程.

I have an interface that I am writing using tkinter. Inside that interface, I have a matplotlib plot. In the background, I have zmq connecting to a server to get data. I am using python's multiprocessing module with a Queue sharing data and a Process running for all of the zmq communication.

在 GUI 中,我可以设置一个按钮来使用以下功能更新绘图:

In the GUI, I can set up a button to update the plot with the following function:

def addData(self):
    if not self.data.empty():
        print "Have Data!"
        self.hist.addQueue(self.data)
        self.hist.updatePlot()
    else:
        print "No Data"

但是,如果我尝试创建另一个基本上将其放入 while True 的进程,我会收到以下错误:

However, if I try to create another process that basically puts this inside of a while True, I get the following error:

X Error of failed request:  RenderBadPicture (invalid Picture parameter)
  Major opcode of failed request:  139 (RENDER)
  Minor opcode of failed request:  7 (RenderFreePicture)
  Picture id in failed request: 0x160000a
  Serial number of failed request:  2686
  Current serial number in output stream:  2690
[xcb] Unknown sequence number while processing queue
[xcb] Most likely this is a multi-threaded client and XInitThreads has not been called
[xcb] Aborting, sorry about that.
python: ../../src/xcb_io.c:274: poll_for_event: Assertion `!xcb_xlib_threads_sequence_lost' failed.
fish: Job 1, "python clientGUI.py " terminated by signal SIGABRT (Abort)

关于此错误的任何信息似乎都与我正在执行的操作有关.

I can't find anything about this error that seems to be related to anything that I'm doing.

如果需要,我可以提供代码的其他部分,但是有很多我不想让这个问题困扰的代码.

I can provide other parts of my code if needed, but there's a good bit of code that I didn't want to floood the question with.

推荐答案

请原谅我没有跟踪你的验尸记录

Excuse me for not following your post-mortem trails


第 0 步:(重新)调整组件的概念

座右铭:虽然可以调试错误定向的架构,但与更好、更直接的设计相比,由此产生的效率相当低


STEP 0: (re)-align the concept of components

motto: while debugging a mis-directed architecture is possible, the resulting efficiency is rather low compared to a better and a more straightforward design

组件清单:

Tkinter 是一个非常聪明的框架,它围绕 .mainloop() (中央调度程序)和允许对其他任务(包括首尾)进行软实时调度.对消息代理池的计划/预定查询.

Tkinter is a very smart framework that works around .mainloop() ( a central scheduler ) and allows for a soft-real-time scheduling of additional tasks / incl. a planned/scheduled querying of a pool of messaging agents.

Queue 是一种中介服务,它在一个端点上接收任何消息并将(所有 此类消息)传递给相对端点.由于所有消息的非托管无上下文传递到接收点,基于队列的自动化对于具有软调度的分布式系统中的 GUI 刷新功能代理是不可行的.(以下是关于state-full-GraphModelAGENT的注释,它更适合与 Tkinter.mainloop()

Queue is a mediator-service that on one endpoint receives any message(s) and delivers (all of such messages ) to the opposite endpoint. Due to the unmanaged context-less delivery of all messages to the receiving point, the Queue-based automation is not feasible for the GUI-refresh functionality agent in a distributed system with soft-scheduling. ( ref. remarks below on a state-full-GraphModelAGENT, that is better equipped for the task of co-integration with Tkinter.mainloop()

进程 允许运行单独的子进程并不仅通过Tkinter任务分配角色(通过指定时间段触发的 .mainloop在规定的时隙中调用)()和/或事件触发的回调),还可以运行完全独立的 << __ StateStateFullGraphAGENT_>> 将有两个职责:

Process allow to run separate sub-processes and distribute roles not only via Tkinter tasks ( called in pre-scribed time slots via time-triggered .mainloop() and/or event-triggered callback(s) ) but also to run a fully self-contained <<_aStateFullGraphAGENT_>>, that will have two responsibilities:

[a] 与Tkinter通信以与Tkinter的 SIGRTU_aRequestToUpdate

[a] communicate with Tkinter to update in-sync with Tkinter's SIGRTU_aRequestToUpdate

+

[b] 与服务器"进行通信,更新 AGENT 的内部 GUI-ModelPART(无需将其推送给任何第三方,通过 FIFO-Queue 减少(过载)加载 GUI-VisualPART(GUI-VisualPART 不必遭受不再需要处理和重新绘制 GUI 模型的所有过去"状态,而是变成一个轻量级的Repaint-On-Demand 过程,只处理最近的图的状态(已经组装并持续(从 Tkinter 异步......)维护在 aStateFullGraphAGENT 中)

[b] communicate with "server" to update AGENT's internal GUI-ModelPART ( without any push thereof to any third-party, the less to (over)load the GUI-VisualPART via a FIFO-Queue ( GUI-VisualPART does not have to suffer from having to handle and repaint all the "past" states of the GUI-Model, but becomes a lightweight Repaint-On-Demand process, dealing with just the most recent state of the graph ( already assembled and continuously ( async from Tkinter ... ) maintained in aStateFullGraphAGENT )

-避免必须提供已过时的所有"GUI状态"的 FIFO队列

-- avoid FIFO-Queue that has to deliver all "GUI-states", that 've become obsolete

++添加 aStateFullGraphAGENT 来保持最近"GUI状态

++ add aStateFullGraphAGENT to maintain the "recent" GUI-state

++ 使用 ZeroMQ 智能进程间消息传递层,没有任何线程间阻塞

++ use ZeroMQ intelligent process-to-process messaging layer without any inter-thread blocking

ZeroMQ 相关的消息开销是微秒级的,这不会对任何 Repaint-On-Demand 与 GUI 相关的操作产生不利影响,因此有很多安排Tkinter刷新率的自由度,可以是 .mainloop()计划的,也可以是事件驱动的.

ZeroMQ-associated messaging overhead is in the order of microseconds, which does not adversely impact any Repaint-On-Demand GUI-related operations, so there is a lot of freedom to arrange the Tkinter refresh-rate, be it the .mainloop()-scheduled or event-driven.

参考: >>>https://stackoverflow.com/a/25769600/3666197

Ref.: >>> https://stackoverflow.com/a/25769600/3666197

参考: 项目 2 中的处理时间 >>> https://stackoverflow.com/a/25530099/3666197

Ref.: Processing times in Item 2 >>> https://stackoverflow.com/a/25530099/3666197

这篇关于通过另一个过程在Tkinter GUI中更新Matplotlib图的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆