Note that there are some explanatory texts on larger screens.

plurals
  1. POAccessing the main thread in a TKinter script?
    primarykey
    data
    text
    <p>I think understand why I am receiving the following error <code>TclStackFree: incorrect freePtr. Call out of sequence?</code> but I am not sure how to fix the problem.</p> <h2>Summary of my Script</h2> <p>My <code>Python</code>, <code>TKinter</code> script consists of three active threads. The main thread and two child threads. One of the child threads is responsible for listening for UDP messages and the other is responsible for graphing the data (using <code>Matplotlib</code>) that is received.To my best understanding, the problem is that I am trying to access the gui from the two child threads at the same time. For example, I may be receiving UDP messages and trying to display them on the gui while trying to graph previously received data. This is not uncommon because of the rate at which I am receiving UDP packets (up to 10,000 per second).</p> <h2>Code</h2> <p>The two child threads are spawned using -</p> <pre><code>thread.start_new_thread(self.function, ()) </code></pre> <p><strong>UDP Listener Thread</strong></p> <pre><code>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) </code></pre> <p><strong>Graph Thread</strong></p> <pre><code>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() </code></pre> <p>Like I said, I think the problem is that sometimes the Listener thread is attempting to add the data to the listbox at the same time that the graph thread trys to update the graph. </p> <h2>I Have Tried...</h2> <p>Using <code>root.after_idle(...)</code> before attempting to modify the GUI but this just locks up the main thread. Example: <code>self.listbox.insert(END, data)</code> -> <code>root.after_idle(self.listbox.insert, END, data)</code> (I also called <code>root.after_idle</code> before <code>self.plot.clear()</code>, <code>self.plot.hexbin(...)</code>, and <code>self.canvas.draq()</code>)</p> <p>I have also looked into <code>threading.condition</code> and <code>queue.queue</code> as suggested <em><a href="https://mail.python.org/pipermail/tkinter-discuss/2011-February/002776.html" rel="nofollow">here</a></em> but I couldn't find much information about either. (So I haven't really tried either solution)</p> <h2>Question</h2> <p>How can I access the gui from the child threads without locking it up or causing the error stated above?</p>
    singulars
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload