Я думаю, что понимаю, почему я получаю следующую ошибку TclStackFree: incorrect freePtr. Call out of sequence?
, но я не знаю, как решить эту проблему.
Резюме моего сценария
Мой сценарий Python
, TKinter
состоит из трех активных потоков. Основной поток и два дочерних потока. Один из дочерних потоков отвечает за прослушивание сообщений UDP, а другой отвечает за графическое отображение полученных данных (с использованием Matplotlib
). Насколько я понимаю, проблема в том, что я пытаюсь получить доступ к графическому интерфейсу из двух дочерних потоков. в то же время. Например, я могу получать сообщения UDP и пытаться отобразить их в графическом интерфейсе, пытаясь отобразить ранее полученные данные. Это не редкость из-за скорости, с которой я получаю пакеты 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()
Как я уже сказал, я думаю, что проблема в том, что иногда поток прослушивателя пытается добавить данные в список в то же время, когда поток графа пытается обновить граф.
Я пытался...
Использование root.after_idle(...)
перед попыткой изменить графический интерфейс, но это просто блокирует основной поток. Пример: self.listbox.insert(END, data)
-> root.after_idle(self.listbox.insert, END, data)
(я также называл root.after_idle
перед self.plot.clear()
, self.plot.hexbin(...)
и self.canvas.draq()
)
Я также изучил threading.condition
и queue.queue
, как было предложено здесь, но я не смог найти много информации ни о том, ни о другом. (Поэтому я действительно не пробовал ни одно из решений)
Вопрос
Как я могу получить доступ к графическому интерфейсу из дочерних потоков, не блокируя его и не вызывая указанную выше ошибку?
root.after_idle
? (Подroot
я подразумеваюTK
, извините, я хотел указать это в вопросе) - person Jordan Carroll   schedule 20.11.2013pyplot
, если вы встраиваете (я не могу сказать, встраиваете ли вы). Также не используйтеplot
для имен, это технически не конфликтует сplot()
, но это делает ваш код действительно трудным для чтения. - person tacaswell   schedule 20.11.2013