访问TKinter脚本中的主线程?

时间:2013-11-20 18:49:29

标签: python multithreading matplotlib tkinter

我认为理解为什么我收到以下错误TclStackFree: incorrect freePtr. Call out of sequence?,但我不确定如何解决问题。

我的剧本摘要

我的PythonTKinter脚本由三个活动线程组成。主线程和两个子线程。其中一个子线程负责监听UDP消息,另一个负责绘制接收到的数据(使用Matplotlib)。我最好的理解是,我试图访问gui来自这两个子线程同时出现。例如,我可能正在接收UDP消息并尝试在尝试绘制先前接收的数据时在gui上显示它们。这种情况并不罕见,因为我收到UDP数据包的速率(每秒高达10,000)。

代码

使用 -

生成两个子线程
thread.start_new_thread(self.function, ())

UDP侦听器线程

def Listen(self):
    if self.udpClient.IsConnected():
        while True:
            #Listen for messages
            data = self.udpClient.listen(1024)
            #Add the data to the gui
            self.AddNewData(data)
            if self.disconnectFlag:
                break

def AddNewData(self, data):
    self.listbox.insert(END, data)
    receivedData.append(data)

图表主题

def UpdateGraph(self):
    while True:
        if readyToGraph:
            self.plot.clear()
            self.plot.hexbin(data[0], data[1], bins = "log", extent = self.extent)
            self.canvas.draw()

EDIT: 
if __name__ == "__main__":
    root = TK()
    gui = MainWindow(root, "Receiver")
    root.mainloop()

就像我说的那样,我认为问题在于,有时监听器线程试图在图形线程尝试更新图形的同时将数据添加到列表框中。

我试过......

在尝试修改GUI之前使用root.after_idle(...),但这只是锁定主线程。示例:self.listbox.insert(END, data) - > root.after_idle(self.listbox.insert, END, data)(我在root.after_idleself.plot.clear()self.plot.hexbin(...)之前也称self.canvas.draq()}

我还按照 here 的建议调查了threading.conditionqueue.queue,但我找不到有关这两者的更多信息。 (所以我还没有尝试过任何一种解决方案)

问题

如何从子线程访问gui而不将其锁定或导致上述错误?

1 个答案:

答案 0 :(得分:0)

以下是tkinter-discuss邮件列表中讨论内容的链接:  https://mail.python.org/pipermail/tkinter-discuss/2013-November/thread.html

这是本质:

  

您好,

     

afaik after()/ after_idle()调用不是线程安全的!

     

在我的研究导致代码安德烈亚斯提供我找到了   event_generate()方法是调用tk的唯一线程安全方式   线程,而不让它进行轮询。 (如Guido和   在其他页面上看到其他人似乎都在调查...为什么?)

     

brgds,

     

- Jan