通过另一个进程更新tkinter gui中的matplotlib图

时间:2015-01-12 00:56:45

标签: python matplotlib tkinter zeromq python-multiprocessing

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

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

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内的进程,我会收到以下错误:

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)

我找不到任何与我正在做的事情有关的错误。

如果需要,我可以提供我的代码的其他部分,但是有一些代码我不想解决这个问题。

1 个答案:

答案 0 :(得分:1)

  

请原谅我没有关注您的验尸路径


步骤0 :(重新) - 对齐组件的概念

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

  

组件清单:

Tkinter 是一个非常智能的框架,适用于 .mainloop() (中央调度程序)并允许进行软实时调度附加任务/包括计划/预定查询消息代理池。

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

共同整合的任务

Process 允许不仅通过Tkinter任务运行单独的子流程并分配角色(通过时间触发.mainloop()和/或预先设定的时间段调用事件触发的回调())以及运行完全独立的 <<_aStateFullGraphAGENT_>> ,这将有两个职责:

[a] 与Tkinter沟通,与Tkinter的 SIGRTU_aRequestToUpdate

同步更新

+

[b] 与“服务器”进行通信以更新AGENT的内部GUI-ModelPART(无需向任何第三方推送,通过{更少(过度)加载GUI-VisualPART {1}}(GUI-VisualPART不必处理和重新绘制GUI模型的所有“过去”状态,而是变成一个轻量级的 FIFO-Queue 进程,处理只有最新的图形状态(已经组装并连续(来自Tkinter的异步...)维护在Repaint-On-Demand


第1步:解决方法

  

- 避免 aStateFullGraphAGENT 必须提供已经过时的所有“GUI状态”

     

++添加 FIFO-Queue 以维持“最近的”GUI状态

     

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

与ZeroMQ相关的消息传递开销大约为几微秒,这不会对任何 ZeroMQ 与GUI相关的操作产生负面影响,因此可以自由地安排Tkinter刷新-rate,无论是Repaint-On-Demand - 预定的还是事件驱动的。

参考:&gt;&gt;&gt; https://stackoverflow.com/a/25769600/3666197


第2步:验证/调整GUI重绘延迟/开销的可行性

参考:第2项中的处理时间&gt;&gt;&gt; https://stackoverflow.com/a/25530099/3666197