Мы реализовали распределенный чат, использующий графический интерфейс Tkinter. Когда я обновил свою систему до Fedora18, я получаю исключения при вызове события Tkinter, почти такие же, как описано loop">здесь:
Exception in thread Thread-1:
Traceback (most recent call last):
File "/usr/lib64/python2.7/threading.py", line 551, in bootstrap_inner self.run()
File "/usr/lib64/python2.7/threading.py", line 504, in run self.target(*self.__args, **self.__kwargs)
File "/hachat/peer.py", line 156, in startRecvLoop
self.processMessage(msg, addr)
File "/hachat/peer.py", line 222, in processMessage
self.gui.receive(msg)
File "/hachat/gui.py", line 74, in receive
self.textfenster.insert(END,msg.name+": "+msg.text+'\n')
File "/usr/lib64/python2.7/lib-tk/Tkinter.py", line 2986, in insert
self.tk.call((self._w, 'insert', index, chars) + args)
TclError: out of stack space (infinite loop?)
Вот вырезка из класса gui:
import Tkinter
import ScrolledText
import tkMessageBox
import tkSimpleDialog
import threading
class gui(object):
def __init__(self, parent):
self.root = Tkinter.Tk()
self.textfenster = ScrolledText.ScrolledText(self.fpopup,width=90,height=24,background='white')
self.textfenster.pack(fill=Tkinter.BOTH, expand=Tkinter.YES)
def run(self):
self.guiRunThread = threading.Thread(target=self.root.mainloop())
self.guiRunThread.daemon = True
self.guiRunThread.start()
def receive(self,msg):
self.textfenster.insert(Tkinter.END,msg.name+": "+msg.text+'\n')
self.textfenster.see(Tkinter.END)
Исключение появляется только в моей системе, причина, по-видимому, в том, что tk не был скомпилирован с поддержкой потоков. Я должен избавиться от этого Exeption - поскольку программа распространяется, ее нужно запускать на разных системах. Поэтому я спрашиваю, как избавиться от этого исключения, а также подсказку, чтобы получить tk для поддержки потоков. Я использую Python версии 2.7.3, Tcl/Tk версии 8.5. import Tkinter; Tkinter.Tk().tk.eval("puts $tcl_platform(threaded)")
также возвращает исключение.
gui.receive
из другого потока, независимо от того, компилируете ли вы все с поддержкой потоков или нет. Другой вопрос - позвонитьevent_generate
, что совсем другое. Измените свой код, чтобы использоватьQueue
Python для связи между потоками. - person mmgp   schedule 25.01.2013gui.receive
вызывается не из другого потока, а извне gui-потока. - person wedel   schedule 25.01.2013gui.receive
вызывается из другого метода вне потокаgui.mainloop
. это работает! только в моей системе выбрасывается исключение. - person wedel   schedule 26.01.2013target=self.root.mainloop()
, как показано выше, является одним потоком. Методgui.receive
просто вызываетTkinter.insert
и не является частью этого потока. Это действительно работает на всех других системах! - person wedel   schedule 27.01.2013